Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching generic non-fatal exceptions [closed]

Conventional wisdom suggests we should only catch the specific exception types we're expecting:

try
{           
    int.Parse(str); //I am aware of TryParse(), this is just for the sake of example
}
catch (FormatException ex)
{
    Console.WriteLine (ex);
}
catch (OverflowException ex)
{
    Console.WriteLine (ex);
}

However, sometimes we don't really care which exception happened (as long as it's not fatal), maybe because we just want to let the user know an error occurred. In these cases we can do something like this:

try
{           
    Foo();
}
catch (Exception ex)
{
    if (IsCriticalException(ex))
    {
        Environment.FailFast("System Error", ex);
    }

    Console.WriteLine ("Error running Foo: {0}", ex);
}   

Where IsCriticalException can be implemented similarly to System.ClientUtils.IsCriticalException. I am generally in favor of this approach for a couple of reasons:

  1. Some methods can throw many exception types and it can be cumbersome to catch them all. For example, File.Open can throw nine different types of exceptions.
  2. Some methods can throw undocumented exceptions. This is either due to lacking documentation, or due to some bug. For example, ICommunicationObject.Close can actually throw ArgumentException due to an obscure bug. Some methods cannot even know statically which exceptions could be thrown by them, since they load other modules / plugins dynamically. Supposedly they could wrap all such "external" exceptions with their own known exceptions, but I believe not all of them do.

The critics of this approach argue that a method's exceptions are part of its contract. If an exception is thrown that is not part of this contract, we should assume its state is corrupt. We will have also discovered a bug in the method (one we otherwise would not have spotted since we'd have swallowed the unexpected exception). We could then relay this bug to the framework's developers, and this is a win - especially if those developers are in our company, so we've "helped ourselves" so to speak.

I admit, the critics present valid points, but I feel they are a bit idealistic. Practically, I think generic non-fatal exception catching makes sense in a lot of situations. Am I making sense?

Related reading:

  • How to Design Exception Hierarchies
  • Vexing exceptions
like image 697
Ohad Schneider Avatar asked Jan 06 '14 18:01

Ohad Schneider


People also ask

Is it OK to catch generic exception?

Don't catch generic Exceptions While this seems harmless, some unintended side effects could result. For example, if className() is null, Class. forName() will throw a NullPointerException , which will be caught in the method.

Which exceptions should be caught?

You should catch the exception when you are in the method that knows what to do. For example, forget about how it actually works for the moment, let's say you are writing a library for opening and reading files. Here, the programmer knows what to do, so they catch the exception and handle it.

Should you catch specific exceptions?

The good practice recommends catching specific exceptions so the program can handle different situations well. Java doesn't prohibit you from catching one for all, but when doing so, you should have good reasons to do that.

What happens if you don't catch an exception C#?

In C#, the catch keyword is used to define an exception handler. If no exception handler for a given exception is present, the program stops executing with an error message. Don't catch an exception unless you can handle it and leave the application in a known state.


1 Answers

Conventional wisdom suggests we should only catch the specific exception types we're expecting

Actually, I think you should catch exactly those exceptions, that you can handle. There is no use in catching exceptions just to rethrow them and it does not make sense to let those exceptions pass that you would have had a cure for.

In your above example, I think having a catch-all block would have been fine, after all not converting that string is a recoverable error, no matter what exception pops up (except for OutOfMemoryException, which cannot be handled anyway because any attempt at handling would use memory).

like image 187
nvoigt Avatar answered Sep 30 '22 18:09

nvoigt