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:
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:
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.
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.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With