Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What benefit does the new "Exception filter" feature provide?

C# 6 has a new feature called "exception filtering"

The syntax is like this:

catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00042)   {       //Do something here  }   

I couldn't help but wonder what the benefit of that is over the current approach:

catch (Win32Exception exception)    {      if (exception.NativeErrorCode == 0x00042)      {           //Do something here       } } 

Is it a big deal that filtering happen before the curly bracket? Perhaps in relation to performance or security?

like image 212
stackunderflow Avatar asked Nov 22 '14 20:11

stackunderflow


People also ask

What would be a good reason to use exception filter?

Exception filters are preferable to catching and rethrowing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was rethrown.

Why we use exception filters in MVC?

Exception filter in MVC provides an ability to handle the exceptions for all the controller methods at a single location. This is by creating a class, which inherits from the FilterAttribute and IExceptionFilter interface.

What is exception filter?

Exception Filter provides an ability to handle the exception for all the method, controller classes in one place. Exception filters execute when some of the exceptions are thrown from an action. The exception can be anything. This is by creating a class that inherits from IExceptionFilter and FileAttribute interface.


1 Answers

The Exception Filters feature in C# 6.0 provides various benefits. Here's an explanation of some (ordered by my perceived importance)

  • Feature Parity - Exception filters were already implemented in the IL level and the other .Net languages (VB.Net & F#)[1] and as part of building the new compiler for C# and VB.Net (project "Roslyn") many features existing in one language and lacking in the other were implemented[2].

  • Crash Dumps - Exception filters don't modify the stack. which means that if it gets dumped (in a crash dump) you would be able to know where the exception was originally thrown and not only where it was rethrown (which is irrelevant to the actual problem)[3]

  • Debugging - When an exception enters a catch block, rethrown using throw; and isn't handled anywhere else in the stack (and the exception settings are set to break when the exception is user-unhandled) the debugger would break on throw; instead of where the exception is originally thrown (i.e. in the example below it would break on throw; and not throw new FileNotFoundException();)

  • Multiple catch Blocks - Without exception filters you must catch the exception, check a condition and if it isn't met throw; the exception. The rethrown exception doesn't consider any other catch blocks even if the exception satisfies all the conditions which ultimately results in a single big catch block

    try {     throw new FileNotFoundException(); } catch (FileNotFoundException e) {     if (!e.FileName.Contains("Hamster"))     {         throw;     }     // Handle } catch (Exception e) {     // Unreachable code } 
  • Readability - While you could use a "catch all" catch block with many conditions and throw; when they are not met (while suffering the modification to the stack) it's much clearer to have separate and distinct catch blocks where each handles a specific problem in the appropriate way:

    try { } catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00042)   {  }   catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00011)   {   } catch (IOException) {   } 
  • "Abuse" - You could use exception filters as a way to inspect an exception without handling it. While this is not a main benefit it's a nice side effect. You can have a false-returning logging method and an empty catch block:

    private static bool LogException(Exception exception) {     Console.WriteLine(exception.Message);     return false; }  try { } catch (ArgumentException exception) when (LogException(exception))   {     // Unreachable code. } 

In conclusion, most of C# 6.0 features are small improvements and syntactic sugar, and while exception filters isn't a very big feature it does provide functionality that wasn't possible before.


  1. A C# 6.0 Language Preview

    The other exception improvement in C# 6.0—support for exception filters—brings the language up-to-date with other .NET languages, namely Visual Basic .NET and F#

  2. Languages features in C# 6 and VB 14

  3. New Features in C# 6

    Exception filters are preferable to catching and rethrowing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was rethrown.

like image 59
i3arnon Avatar answered Sep 30 '22 22:09

i3arnon