Question

I'm building the standard 3-tier ASP.NET web application but I'm struggling as to where to do certain things - specifically handling exceptions.

I've tried to have a look around on the web for some examples but can't find any which go as far as a whole project showing how everything links together.

In my data-tier I'm connecting to SQL Server and doing some stuff. I know I need to catch exceptions that could be raised as a result but I'm not sure where to do it.

From what I've read I should be doing it in the UI tier but in that case I'm not sure how to ensure that the connection to the database is closed. Is anyone able to clarify how to do this? Also if anyone knows as to where I could find an example 3-tier web application that follows best practices that would be great too.

thanks

Was it helpful?

Solution

There are no easy answers or patterns that will ensure success. Just like your validation strategy, your exact exception-handling strategy is specific to your exact situation, and is often a trade-off between time and comprehensiveness. There is some good advice we can give though:

  • Don't ever hide the stack-trace; don't ever use "Rethrow" unless for security purposes you want to hide what happened.
  • Don't feel you need error handling everywhere. By default, in your lower tiers, letting the actual error percolate up to the top tier is not bad. The UI/Controller is where you have to really decide how to react to something going wrong.
  • At every point, as yourself what exactly you want to happen if something goes wrong. Often, you won't be able to think of anything better than to just let it go up to the top layer or even to the client machine. (though in production turn of verbose reporting.) If this is the case, just let it go.
  • Make sure you dispose of unmanaged resources (Anything that implements IDisposable.) Your data access is a great example. Either (A) Call .Dispose() for your (especially) connection, command, datareader etc. in the Finally block, or (B) use the Using Syntax/Pattern which makes sure that proper Disposing happens.
  • Look for places where errors are likely and where you can look for certain errors, react (by retrying, waiting a second retrying, trying that action a different way, etc.) and then hopefully succeed. Much of your exception handling is to make success happen, not just to report failures well.
  • In data layer, you must consider what to do if something goes wrong in the middle of a multi-step process. You can let the actual error percolate up, but this layer must handle tidying things up after an error. You'll sometimes want to use transactions.
  • In an asynchronous situation (either (A.) because of multiple threads or (B.) because business logic is processes separately on "task machines" and such and acted upon later), you in particular need to have a plan for logging errors.
  • I'd rather see "error handling code" in 25% of your app than 100%. 100% means you probably wanted it to look and feel like you have error handling. 25% means you spent time handling exceptions where they really needed to be handled.

OTHER TIPS

Just a side point that may steer your thinking: if you have any type of volume that may result in concurrency issues (deadlocks) you will want your application to detect that particular SQL error and retry the operation (e.g. transaction). That argues for some exception handling at either the data or business tiers.

-Krip

I believe its best practice to handle exceptions at the last responsible moment. This usually means at the UI level (i.e., the Controller in a MVC app or in the codebehind in a traditional asp.net app). Its at this high level that your code "knows" what the user is asking, and what needs to be done if something doesn't work.

Handling exceptions lower down in the call stack usually results in calling code not being able to handle exceptional situations properly.

In your data tier, you would use the standard patterns (e.g., the using statement for IDisposables such as the SqlConnection), document exceptions you know may occur (don't do this for out of memory or other rare cases), and then let them flow up the call stack when they do. At the most you might want to catch those exceptions and wrap them in a single exception type, in situations where MANY exceptions may have to be handled by callers.

If you need to "clean up" stuff before letting exceptions go, you can always use a finally block to clean up. You don't have to catch in order to use a finally block.

I don't know of any examples of small websites which are designed to highlight proper exception handling, sorry.

This is not a specific answer to your question but if you are interested in best practices I would look at Microsoft Patterns and Practices:

Application Architecture Guide

Web Applications Guides

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top