tags:

views:

740

answers:

11

Consider this scenario: I have 3-layer app, when the user click on the button the button event handler calls a method in biz layer that do whatever with data my button event handler supply and then pass that data to the data Access layer which sends them to the backend database. The question is where to put the try catch? In the data layer, in biz layer, in presentation layer or maybe put it around all of them? What the best strategy to represent exception handling as in this scenario?

+2  A: 

definitely put a try catch closest to the user -- because in that location you can translate it into something meaningful for your user.

Deeper try catches could only be needed if you intend to do something with them -- for example, handle the exception, or perhaps log and rethrow the exception.

Leon Bambrick
+21  A: 

We follow

Do not catch exceptions if you do not know what to do with it.

We never handle any exceptions which we cannot handle or default. It gets bubbled up and we handle it at the application level.

Say if you can default a value, for a businesss object, then you can handle it in the business layer.

Ramesh
Yeah, catch the exception where you're able to deal with it. If you don't know what to do with it, don't catch it. (And sometimes, "catch it and ignore it" might be the valid thing to do with it, so do that.)
jalf
@Ramesh: Nice answer +1
Kb
A: 

It just depends on where you actually want to do something about it. Generally I catch it in the business layer, and then log it and possibly call some ui function to display a message to the user.

I consider what to do with errors a business rule. It should be separate from the data layer or ui layer.

Jacob Adams
A: 

The general answer would be: catch anytime you can handle what is being thrown. That is, the decision is quite simple. For example, catch exceptions that arise when creating an object you need.

Eduard - Gabriel Munteanu
I agree with the 1st part of the answer but not with the example, if creation of an object fails you not automatically know how to handle that.
Henk Holterman
Yes, of course. If you can't handle it, let it propagate.
Eduard - Gabriel Munteanu
+2  A: 

Probably best to use try catch in all layers but only silently catch the exceptions in the UI layer. In the biz and data access layers you should probably catch the exception and record the information, before re-throwing e.g.

try
{
    //do something 
}
catch(Exception ex)
{
    LogFile.WriteLine(ex.ToString());
    throw;
}

Note: do not write:

throw ex;

as this will clear all the useful stack information from the exception.

mdresser
@mrdresser: Why you should log the exception in each layer and not log it once in for all where we handle the exception / if never handled in UI layer? stack trace would always give the whole information
Ramesh
i'm with Ramesh on that one. Catching for just the sake of logging is tempting... but it's just a lot of busy work you don't need and cnan safely be avoided.
Leon Bambrick
Plus if you log it in each layer, you could have multiple log entries for the same exception.
Jacob Adams
I agree, only the exceptions once. I don't like the process of catching, logging and rethrowing at all. This type of logging should be handled at a much higher level where it can be done consistently and where logic can be applied to how and if certain exceptions are logged.
Jim Petkus
A: 

Always try/catch at the top level or contoller level.

Kb
A: 

UI is just for presentation. You don't catch exceptions there, because figuring out what to do with it means logic. That belongs in business or controller layers. At worst, you catch the exception and map it to an appropriate, user-friendly error message that is then sent to the presentation for display.

duffymo
A: 

Put the try-catch where you are sure you won't just swallow the exception. Multiple try-catch blocks in various layers may be OK if you can ensure consistency.

For example, you may put a try-catch in your data access layer to ensure you clean up connections properly. But as you can't do much more there you should probably rethrow the exception.

Moving to business layer, you may put try-catch across multiple database operations which you want to proceed atomically. In this case, may be you should rollback everything or put things in a consistent state, log the exception somewhere. Swallowing or rethrowing should be decided on case by case basis.

Your presentation layer should always catch all exceptions, be it some web application, script running in a browser or some rich client application. You may not be able to understand the exception completely, but at least you can ensure that your application does not die in the face of a user.

Of course, its just a piece of advice. YMMV. :)

Tanveer Badar
I would say that if you are concerned with cleaning up connections in your DAL that you should be using Try-Finally blocks (or using blocks) not Try-Catch. There is no need to specify a Catch block if you are just going to rethrow the exception without handling it.
Jim Petkus
Oh yeah. My apologies, I mean try-finally but didn't notice. :(
Tanveer Badar
A: 

When I have a multi-layer architecture like this (which is a lot) I will often have a try/catch at more than one layer. For example, a try/catch in the persistence layer that catches an SQLException, does what the persistence layer needs to do (like notify an admin, for example) then throws a new exception that will make sense to some code that calls the persistence layer. An example might be PersistenceException. The next layer up doesn't care about who should be notified to re-start the database, but it does care that it couldn't save user state, so it might catch the PersistenceException and tell the user that his new phone number wasn't stored in the database.

Don Branson
+1  A: 

The exception handling mantra is: "Throw early, catch late". You want to catch exceptions at the last possible moment, but you want to throw them immediately (don't perform a bunch more processing after determining something is wrong and then throw an exception). If you cannot "handle" the exception, then don't catch it.

In most circumstances, Try...Finally blocks should be far more common in your code than Try...Catch.

Jim Petkus
A: 

You only want to use try catches to manage unhandled code. An example is I have a COM object I am communicating with and I don't want it to stay open and create a memory leak. The other acceptable alternative is to catch errors on events in your database before allowing the exception to continue.

You do not ever want to use try catches to handle situations where you are unsure you code will work and want a backup plan.

So where does that leave you when apps blow up, use custom error pages to indicate a problem has occurred in your web apps and for thick clients parse code off into worker threads so they don't blow up your main thread if they fail. Good luck!

Al Katawazi