How it works...

Imagine being able to view the exception information in a log file with all the local variable values available. Another interesting point to note is the return false statement in the Log(ex) method. Using this method to log the error and return false will allow the application to continue and have the exception handled elsewhere. As you know, catching Exception ex will catch everything. By returning false, the exception filter doesn't run into the catch statement, and more specific catch exceptions (for example, catch (FileNotFoundException ex) after our catch (Exception ex) statement) can be used to handle specific errors. Normally, when catching exceptions, FileNotFoundException will never be caught in the following code example:

catch (Exception ex)
{
}
catch (FileNotFoundException ex)
{
}

This is because the order of the exceptions being caught is wrong. Traditionally, developers must catch exceptions in their order of specificity, which means that FileNotFoundException is more specific than Exception and must, therefore, be placed before catch (Exception ex). With exception filters that call a false returning method, we can inspect and log an exception accurately:

catch (Exception ex) when (Log(ex))
{
}
catch (FileNotFoundException ex)
{
}

The preceding code will catch all exceptions, and in doing so, log the exception accurately but not step into the exception handler because the Log(ex) method returns false. Another implementation of exception filters is that they can allow developers to retry code in the event of a failure. You might not specifically want to catch the first exception, but implement a type of timeout element to your method. When the error counter has reached the maximum iterations, you can catch and handle the exception. You can see an example of catching an exception based on a try clauses' count here:

public void TryReadXMLFile(string fileName)
{
bool blnFileRead = false;
do
{
int iTryCount = 0;
try
{
bool blnReadFileFlag = true;
if (blnReadFileFlag)
File.ReadAllLines(fileName);
}
catch (Exception ex) when (RetryRead(ex, iTryCount++) == true)
{
}
} while (!blnFileRead);
}

private bool RetryRead(Exception e, int tryCount)
{
bool blnThrowEx = tryCount <= 10 ? blnThrowEx =
false : blnThrowEx = true;
/* Log the error if blnThrowEx = false */
return blnThrowEx;
}

Exception filtering is a very useful and extremely powerful way to handle exceptions in your code. The behind-the-scenes workings of exception filters are not as immediately obvious as one might imagine, but here lies the actual power of exception filters.