|
06 Mar 2015 by Charlie
Unpredictable Behavior With C# 6 Exception Filters
c#
EDIT: A reader has reported this behavior as a bug to the core CLR team (Exception filters have different behavior when invoked via reflection and the filter throws an exception). The issue is Open at the time of writing. I assume you know about the Exception Filters feature introduced in C# 6.0. If not you can read a short post about it here: C# 6 Exception Filters and How they are much more than Syntactic Sugar The ExpectedWith Exception Filters, we can now specify a condition along with the catch block, and the catch block will only execute if the condition is satisfied. So we can have a function returning bool, as a condition. Now what happens if the condition itself throws an exception. The expected behavior in this case is, the exception inside the condition is swallowed, and the condition is assumed to be false. Consider the following code:class Program { public static void Main() { TestExceptionFilters(); } public static void TestExceptionFilters() { try { throw new Exception("Original Exception"); } catch (Exception ex) when (MyCondition()) { Console.WriteLine(ex); } } public static bool MyCondition() { throw new Exception("Condition Exception"); } } When the "Original Exception" gets thrown, before entering the catch block the MyCondition is checked. But as it throws an exception, it is swallowed and the condition is assumed to be evaluated as false, and you get the following unhandled exception. System.Exception: Original Exception The UnepxectedNow for the weird part. In the above code, instead of calling TestExceptionFilters() directly I use reflection to invoke it. The code is exactly the same except, we are calling the function TestExceptionFilters in a different way:class Program { public static void Main() { var targetMethod = typeof(Program).GetMethod("TestExceptionFilters"); targetMethod.Invoke(null, new object[0]); } public static void TestExceptionFilters() { try { throw new Exception("Original exception"); } catch (Exception ex) when (MyCondition()) { Console.WriteLine(ex); } } public static bool MyCondition() { throw new Exception("Condition Exception"); } } Now when we run it, we would again get an unhandled exception. But this time the exception is System.Exception: Condition Exception So what kind of Exception would get thrown actually depends on the way you call the function. I really hope this is a bug and would get fixed in the coming release.
I have a utility in tools section "Online C# Snippet Compiler" which allows you to run code online. I use reflection to invoke the Main() method, where I saw this unexpected behavior in a snippet shared on StackOverflow. Comments |