Exception filters are not new. Its been there for a long time (at least for than a year) as it is been released with .NET framework 6.0. But I do see developers don’t know the basic advantages of using exception filters and use code inside catch to determine problems. Let us look how exception filters can help you determine the actual exception during your execution.
First of all, if you think exception filter is yet another language construct which C# compiler produces during compilation, I would strongly object that. Exception filters are a CLR Construct and it is directly compiled and converted as filters in Intermediate language. Let us see this using a small code block :
public class Test { public void RunMe() { try { this.ThrowException(); } catch(NotImplementedException ex) when (ex.InnerException == null) { Console.WriteLine("Innerexception is null"); this.Log(ex); } catch(NotImplementedException ex) { this.Log(ex); } catch(Exception ex) { this.Log(ex); } } private void Log(Exception ex) { Console.WriteLine(ex.Message); } private void ThrowException() { throw new NotImplementedException(); } }
In the code above there is clearly an exception being thrown from ThrowException method, and this is catched by the first catch that includes the exception filters. Let us see how the IL looks like here :
You can see the last line of the function after ret statement of L_0036 there is an execution instruction to ensure that L_000c is called. Hence the filter is written and executed by the CLR itself and IL has a keyword present to determine filters intrinsically.
Note : If you minutely see the IL code, the other handlers are not there because C# compiler optimized the code and removed the unnecessary code from IL.
Now coming back to the differences, when you are debugging your code it is important for you to get your CLR stack open such that you can clearly determine the problem, with normal exception handling, you will lose the CLR stack and you have to only rely on the StackTrace property of exception object. Let us look into the details with example :
In the code above, the runtime encounters the DivideByZeroException but strangely while debugging you are in a line where you have clearly missed out the actual reason why the exception happened, and you cannot determine the line which causes the exception. I know you can use advanced debugging tools like Intellitrace inside visual studio to rewind the execution, but it is not always fruitful.
Let us consider rewriting the existing code using exception filters and see the result how visual studio shows the problem.
Now in the code above, with exception filters, you can ensure that the CLR Stack is kept intact, and you can see in this case the exception is encountered on the very line where the exception has occurred with the local variables and everything kept intact for you.
I hope this post will help you use this cool feature more gracefully and help you quickly find your common errors.
Thanks
Pingback: Compelling Sunday – 13 Posts on Programming and QA
Pingback: Dew Drop - July 5, 2016 (#2280) - Morning Dew
Pingback: Weekly Links #22 | Useful Links For Developers
Pingback: Top Ten Most Popular Developer Links for the Week Of July 11th, 2016 - Dmitry Lyalin