Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub
Many of the other C# 6 features I’ve covered are implemented using syntactic sugar, exception filters isn’t. This has been in the deep parts of .NET for some time and in C# 6 it is getting surfaced finally. This is very much the introduction to Exception Filtering, and I have another post with advanced topics I would love for you to read.
Catching Exceptions
Catching exceptions today uses the exceptions type as the condition for the the catch block.
try { // code which could throw exception } catch (HttpException ex) { // catching only HttpExceptions }
In the above code, any HttpException will be caught but any exception of any other type won’t.
try { // code which could throw exception } catch (HttpException ex) { // catching only HttpExceptions } catch (Exception ex) { // catching everything except HttpExceptions }
We can catch everything by catching the base Exception class. Order here matters, but the compiler will help prevent you from hurting yourself:
Today, if you want more fine grain control of what a catch block responds to you need to do that in the catch block itself. For example, handling an exception differently based on values in the exception.
try { // some code } catch (HttpException ex) { if (ex.HttpCode == 401) { // need to do an authenticate } else { // some other HTTP error we need to handle } }
Another good example is logging, based on a setting you may want to log or not log exceptions.
try { // some code } catch (HttpException ex) { if (loggingTurnedOn) { // log it } throw; }
Exception Filters
Exception Filters adds a way to have additional requirements for a catch block in the form of a boolean expression which we append with the when keyword. We can now rewrite the two examples as follows:
//example 1 try { // some code } catch (HttpException ex) when (ex.HttpCode == 401) { // need to do an authenticate } catch (HttpException ex) { // some other HTTP error we need to handle } //example 2 var loggingTurnedOn = false; try { // some code } catch (HttpException ex) when (loggingTurnedOn) { // log it throw; }
The when clause can take in ANYTHING which evaluates to a boolean expression. You can put ands or ors and chain things together:
when (loggingTurnedOn && ex.HttpCode != 401)
You can pass methods in to the when condition too:
public static bool ThrowException() { //elided } public static void OldPain2() { try { // some code } catch (HttpException ex) when (ThrowException()) { // do something } }
When isn’t if
Lastly, the language chosen for this feature is important, it isn’t IF, because it isn’t an IF statement – it is a WHEN condition. One of the important distinctions around that is that an IF statement supports ELSE and WHEN does not.