0

I don’t have much experience with exceptions and I’m trying to figure out how to use exception handling correctly in real world scenarios. In C#.

In this example I have one top level function, LoadModel, that calls lot of other functions (that call other functions, …):

class Core
{
    public void LoadModel(string file_name)
    {
        try
        {
            // call other functions (that call other functions, …) that may throw exceptions
        }
        catch (Exception ex)
        {
            if (ex is ArgumentNullException ||
                ex is ArgumentException ||
                ex is EncoderFallbackException ||
                ex is InvalidOperationException ||
                ex is XmlException ||
                ex is InvalidDataException ||
                ex is IOException)
            {
                // show error message
            }
            else
            {
                // unsupported exception. system may be unstable. let it crash.
                throw;
            }               
        }
    }
}

I adhered to this rules:

  • All functions report errors using exceptions, i.e. they don’t return error codes. It’s the same paradigm as in .NET framework.
  • If you are inside some lower level function and exception occurs and it’s not appropriate to report the failure to the user at this place, don't catch the exception and let it propagate upwards the call stack.
  • Don’t use empty catch to catch all exceptions at top level. It would hide problems with you app an could destabilize it. Catch only exceptions you know how to recover from.

Question: Is this how you handle exceptions? I.e. I check what exceptions my guarded code generates (considering also all nested functions), decide from which it’s safe to recover and put them into high level catch. I can get the list of exceptions for .NET functions from their documentation and for my own functions I should keep the list of exceptions in their documentation. And this exception list tends to accumulate: a function can throw its own exceptions and exceptions of its nested functions…….It seems error prone to me. Someone adds new exception in some nested function, and your top level catch won’t handle it. With error codes you could do something like "if (error != SUCCESS)" to catch all errors, but you can’t do it with exceptions (if you don’t want to use empty catch).

jkb
  • 1
  • 1
  • 1
    The usual style is to have several catch statements for each exception type rather than a big if statement. – Ben Robinson Oct 16 '13 at 15:27
  • It would be strange to say the least to call an exception "unsupported". All exceptions should be handled gracefully (or "supported") in one way or another. Whether that's by logging it and moving along, throwing up an error message, handling an expected exception and fixing the issue, etc etc. You should *never* have an exception that just crashes your program. That would be called a bug. – tnw Oct 16 '13 at 15:30
  • When I am inside some lower level function, I usually do a try/catch and inside the catch I re-throw the exception (throw ex;). This way it is clearer to know where a exception could raise. – dave Oct 16 '13 at 15:35
  • 3
    @dave **NO**. `throw ex` is absolutely wrong and bad practice. Not only will it ruin your stack trace but it will also indicate that the source of the exception is `throw ex` and *not* where it was actually thrown. To properly re-throw an exception, just use `throw;` [Good example here](http://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-throw-ex) – tnw Oct 16 '13 at 15:36
  • Thanks tnw, your right! use just throw. But it is a good practice to do this and don't leave the exception jump to the function above without control, isn't it? – dave Oct 16 '13 at 15:53
  • @dave: No. Do not catch exceptions just to log then. Let the higher-level code do that. See "[Handling exceptions, is this a good way?](http://stackoverflow.com/questions/2469822/handling-exceptions-is-this-a-good-way)". – John Saunders Oct 16 '13 at 16:25
  • See http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx for suggestions on how categorize and handle exceptions. – William Oct 16 '13 at 16:42

1 Answers1

2

You can catch multiple kinds of exceptions in a cascading manner:

try 
{

  //some code

}
catch (NonGenericException nonGenericEx) 
{

}
catch (MoreGenericException moreGenericEx) 
{

}
catch (Exception mostGenericException) 
{

} 
finally
{
  //this code will always be executed
}
Rob G
  • 3,496
  • 1
  • 20
  • 29