Paul - 9 months ago 45
C# Question

# Catch block never firing inside a LINQ statement

I have some data I am deserializing inside a

Linq
statement:

var scheduledData = results
.Where(o => o.Result.IsValid)
.SelectMany(o => JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response))
.ToList();


This is throwing an error. I never see this error in the debugger. The returned web page lists a 500 error showing this. So I added some handing:

var scheduledData = results
.Where(o => o.Result.IsValid)
.SelectMany(o => {
try {
return JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response);
}
catch {
return new List<CalendarJob>();
}
})
.ToList();


Yes this is really ugly. I only did this so I could put a breakpoint on the
catch
block so I could inspect some values. This is not code I would leave in place! :)

I put a breakpoint on the
return
statement inside the
try
block and also the
catch
block. Then I execute the code. The
try
statement hits and execution is gone. The
catch
block never fires nor does any other code in my method.

Should this
catch
block be allowed in
linq
? I sure thought so?

Yes, I am in debug mode. Yes, I have cleaned and rebuilt. The breakpoint on my try block does indeed hit. I can inspect the value of the string about to be deserialized and the value is not right. It's
""
. I do not mean
string.Empty
, I specifically mean the string contains two bytes and both are the double quote character. The service I am getting the data from is not returning good data. But my
catch
block never fires.

One more thing to note. I put the entire thing into a
try...catch
block and that catch block does hit. Only the one inside
LINQ
does not.

Yes - this will work the way you think it will.

The only time it won't work will be an exception you cannot catch, like a StackOverflowException.

To prove it, just execute the folllowing code in Visual Studio, or Linqpad and observe the breakpoint is hit twice.

var list = new List<string>
{
"a",
"b"
};

list.Select(i =>
{
try
{
return int.Parse(i);
}
catch
{
return 0; // Put a breakpoint here.
}
}).ToList();