Orchard Gems: Exception fatality check

Tags: Orchard, Orchard gems, exceptions, Orchard 1.5, C#

Catching exceptions with the type of the base Exception class is bad practice. "Never catch an exception you can't handle" says the proverb we all know from kindergarten. But what if we get our dependencies injected by requesting objects by their interface types?

Every service in Orchard is constrcutor-injected, and all we can assume about the objects our classes get is their interface. Well, good luck with knowing what exceptions these services can throw :-). Since interfaces won't tell anything about implementations, and exceptions thrown from a method is an implementation detail, we're kind of stuck. I formerly had this problem and I've also opened a discussion about it. Fortunately with the release of Orchard 1.5 the matter is somewhat solved.

Now there is an extension method for exceptions in Orchard.Exceptions.ExceptionExtensions:

    public static class ExceptionExtensions {
        public static bool IsFatal(this Exception ex) {
            return ex is OrchardSecurityException ||
                ex is StackOverflowException ||
                ex is OutOfMemoryException ||
                ex is AccessViolationException ||
                ex is AppDomainUnloadedException ||
                ex is ThreadAbortException ||
                ex is SecurityException ||
                ex is SEHException;
        }
    }

This code was present in previous versions too, but in a private method, not in a public extension method.

Using IsFatal() we can more safely catch base Exceptions if we really don't know what type of exceptions to await but we have to do something if anything goes wrong:

try 
{
    // ...
}
catch (Exception ex)
{
    if (ex.IsFatal()) throw;
    // Handle other exceptions here
}

Here we rethrow the exception if it is a very critical one. I already used this pattern in the Combinator module and you'll see it in the next release.

Happy exception handling!

No Comments

Add a Comment