Avoid Throwing Plain Exceptions

 

Exceptions are tricky things. The mechanics of throwing and catching exceptions is straightforward. However, many developers seem confused about when and how to use exceptions. I can help clear up the difficulty surrounding exceptions. Over the next weeks, I’ll publish content on managing exceptions.

One of the most prevalent exception anti-patterns is the throwing of straight System.Exceptions.

Let’s look at an example:

  if (IsUnableToParse(parser, html))
     throw new Exception("Error parsing HTML");

Why not do this? Why is this a bad idea?

What would we have to do to intercept and manage this exception? Here is a catch statement that would do it:

  catch (Exception ex)
  {
     if (ex.Message == "Error parsing HTML")
        // Do something to handle HTML parsing failure.

     // Rethrow all other Exceptions that we didn't want to catch here! :(
  }

There are two problems:

  1. Throwing raw Exceptions do not allow for isolated catching & handling. We have to catch all exceptions to get to the one we want. All the exceptions we are not interested in we must rethrow. 
  2. We have no choice but to use the Message property to identify the problem. That is a fragile design. It’s conceivable at some point a developer alters the message string to “An error has occurred parsing HTML“. On the face of it, this represents a mere cosmetic change. They may not realise that they have broken the exception’s handling since the string comparison will now evaluate to false.

Apart from fragile Message comparison in a catch statement, when we throw a raw System.Exception, we have condemned it to bubble up to the global exception handler.

Is it right for us to make the thrown exception so ‘slippery’ that we have effectively removed transitive callers’ ability to intercept and handle it?

No, it is not. Throwing and catching/handling exceptions are independent events. We should make it easy for calling functions to handle our custom exceptions—we don’t know which exceptions they can or cannot handle. It’s a mistake to presume they cannot do anything useful with the current exception and for us to doom it to the global exception handler. 

Soon we’ll look at throwing ‘grippier’ exceptions.

Throwing raw System.Exceptions is problematic and best avoided.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply