26
Sep

detecting fatal exceptions

If you haven't read Clemens Vaster's Are You Catching Falling Knives post, you need to. The gist of it is you need to be really careful about overly wide exception catch blocks and be sure you're not catching really bad things.

After reading that article, I'm careful to employ this pattern every time I need to catch a generic exception (i.e. System.Exception):

try  
{
    // whatever work suspicious work that might blow up
}
catch (Exception ex)  
{
    if (ex.IsFatal())
        throw; // get out of the way and let the badness bubble

    //do whatever is appropriate for your situation....
}

Here is the IsFatal() extension method taken from his post:

using System;  
using System.Reflection;  
using System.Runtime.InteropServices;  
using System.Threading;

/// <summary>
/// Utility method for dealing with exceptions 
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1050:DeclareTypesInNamespaces", Justification = "Easier to use if global")]
public static class ExceptionExtensionMethods  
{
    /// <summary>
    /// Utility method for inspectingthe exception graph to determine if there are any falling knives.
    /// http://vasters.com/clemensv/2012/09/06/Are+You+Catching+Falling+Knives.aspx
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    public static bool IsFatal(this Exception exception)
    {
        while (exception != null)
        {
            if (exception as OutOfMemoryException != null && exception as InsufficientMemoryException == null || exception as ThreadAbortException != null ||
                exception as AccessViolationException != null || exception as SEHException != null || exception as StackOverflowException != null)
            {
                return true;
            }

            if (exception as TypeInitializationException == null && exception as TargetInvocationException == null)
            {
                break;
            }

            exception = exception.InnerException;
        }

        return false;
    }
}
comments powered by Disqus