Handling exceptions is a fact of life in C# and sometimes you want to catch an exception but only if certain conditions are true.
Prior to this feature you had to catch the exception, test the condition and rethrow it if it did not apply. By the time you rethrow the stack has already been unwound, so the debugger breaks on your throw line rather than where the exception originally occurred.
C# 6.0 adds a when clause to catch so the condition is evaluated before the exception is caught.
Code
csharp
async Task SaveUrl(string path, Uri uri)
{
var response = await client.GetAsync(uri);
try
{
response.EnsureSuccessStatusCode();
File.WriteAllText(path, await response.Content.ReadAsStringAsync());
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine("Skipping missing page " + uri);
}
}csharp
async Task SaveUrl(string path, Uri uri)
{
var response = await client.GetAsync(uri);
try
{
response.EnsureSuccessStatusCode();
File.WriteAllText(path, await response.Content.ReadAsStringAsync());
}
catch (HttpRequestException ex)
{
if (ex.StatusCode == HttpStatusCode.NotFound)
Console.WriteLine("Skipping missing page " + uri);
else
throw;
}
}Notes
- If the filter returns
falsethe exception is never caught at all and continues up the stack untouched - Filters run before the stack unwinds, so a filter that logs and returns
false(catch (Exception ex) when (Log(ex))) can record exceptions without handling them - C# 6.0 also allows
awaitinsidecatchandfinallyblocks, which was not permitted before