views:

146

answers:

7

1)

1 - Only handle exceptions that you can actually do something about, and
2 - You can't do anything about the vast majority of exceptions

a) I assume that “By not handling an exception” the text is suggesting that we should let the exception bubble up the stack, where runtime will abort our application?!

b) But why is letting the runtime abort the exception preferred over catching an exception, logging it and then informing the user of failure? Only difference between the two is that in the latter case application isn’t aborted

For example, if database goes down, why should the whole program crash ( due to not handling an exception ), if we can instead catch the exception, log it and notify user of failure and that way we can keep the program up and running

2) If you know that exception potentially raised by some block of code can’t be handled, should you include this code inside a try-finally block or is it better to leave it outside any try-finally blocks?

Thank you

+6  A: 

No, the guideline is not to catch an exception you cannot do anything about except at the top-level of your application or thread.

You should try to avoid letting your application crash - log the information somewhere, give a message to your user explaining what happened, and tell them how to report the error to you. Perhaps also try to save their unsaved data in a recovery file so that the next time the application starts it can offer the option to attempt to recover their lost work.

Mark Byers
I agree. And at the top level catch it, log it, and display a sensible dialog to the user if it's an end-user app.
Mikael Svenson
+1  A: 

I think the person you are quoting suggests that you should let the exception bubble up the stack until something higher up can make sense of it or until it reaches the top of the call stack where you do have code that would log it, or display a error message to the user then exit your program if it is fatal, or carry on if it is not.

Sometimes it may be better to not continue executing the program - if you get a OutOfMemoryException for example or some other situation where the programs actions are undefined - a potential disaster.

Callum Rogers
+1  A: 

Hi,

The point is that you don't want to have try/catch blocks nested everywhere in your code as this tends to hide issues with your code. It is better to only implement exception handling where you understand the error and the desired outcome, else don't handle it and let it bubble up.

As for as the errors bubbling up, you should have a global exception handler for these uncaught application errors. This is only implemented in one spot in your app and will allow you to log or present the error to the user. Again this is only implemented in one spot in your app, and is implemented by hooking the application.error event.

Event to hook in .net win forms application:

AppDomain.CurrentDomain.UnhandledException

Event to hook in .net asp.net application:

HttpApplication.Error

Enjoy!

Doug
+1  A: 

I think the key to

Only handle exceptions that you can actually do something about

is that you should only handle the exception if you can carry on from that point in your application.

To take a trivial example.

If you're looking for a file on the user's system and it's not there when it should be you should raise the "file not found" exception. Now if you can recover from this (say by simply recreating the file) then do so and carry on. However, if the file can't be recreated then you shouldn't let your program carry on.

However, this doesn't mean you can't have a top level catch all exception handler in your main program to display a friendly message to the user, perhaps to log the exception or even mail it to you the developer.

ChrisF
+1  A: 

That statement holds true. But it is a reference to catching exception in the deeper layers of application. Basically most of the code we write does not need exception handling. It is only the client part of the application is responsible for catching the error and presenting it to the user - as well as logging.

For example, the same business code/database code can be used in a web application and windows/wpf application and logging/handling could be different and deeper layers do not know about how this will be handled so they need to leave the responsibility to the UI tier.

Aliostad
“It is only the client part of the application is responsible for catching the error…” By client part you mean something like Asp.net application?
+1  A: 

Try looking at it this way... The database goes down. How do you know? Because you get an timeout/an exception/something. But your application probably isnt getting the exception. ADO.NET/Linq to SQL/Entity Framework/Whatever data provider you are using is actually getting the exception and throwing it to your application. To me, this is what that advice is advising: as a component designer, prefer to throw exceptions you can't do anything about.

For the database down example, is there anything the ADO.NET data provider can do? Can it bring a server back up? Repair network connections? Reset permissions? No. So it doesn't handle the exception, it throws it.

The guideline you cite is for component development, not the outer edge of a run-time boundary (a thread or application). At that level, it would be correct to make a decision on how to handle exception that have bubbled that far.

Jonathan Bates
thank you all for your help
+1  A: 

Without knowledge about the context of both statements, stated that both statements apply to methods and classes then they make sense:

A piece of code which calls a method can only handle exceptions for which it has enough information about the context. In most cases a piece of code won't have enough information, to handle all exceptions.

Example: A piece of code, which calls a method SaveData() can handle a DatabaseStorageException when it knows, that it saves data to a database. On the other hand, if the piece of code is programmed in a storage agnostic manner, than catching such a specific exception is not a very good idea. In this case it is better to let the exception pop up the callstack and let some other code handle the exception, which has enough context information to handle it.

Theo Lenndorff