If we had to run our application now, we would obviously receive an error (this is assuming that you actually don't have a file called XMLFile.xml
in your temp
folder). Visual Studio will break on the throw
statement:
Note
You need to add the correct namespace using System.IO
at the top of your code file.
The Log(ex)
method has logged the exception, but have a look at the Watch1 window. We have no idea what the value of blnReadFileFlag
is. When an exception is caught, the stack is unwound (adding overhead to your code) to whatever the actual catch block is. Therefore, the state of the stack before the exception happened is lost. Modify your ReadXMLFile
and Log
methods as follows to include an exception filter:
When you run your console application again, Visual Studio will break on the actual line of code that caused the exception:
More importantly, the value of blnReadFileFlag
is still in scope. This is because exception filters can see the state of the stack at the point where the exception occurred instead of where the exception was handled. Looking at the Locals window in Visual Studio, you will see that the variables are still in scope at the point where the exception occurred:
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:
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:
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:
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.