?
Solved

Exception handling in an n-Tier application-best practices?

Posted on 2009-04-29
10
Medium Priority
?
2,328 Views
Last Modified: 2013-11-12
I have an application that consists of 3 layers: a DAL layer, a BLL layer, and a UI layer. I need to be able to propagate exceptions from the DAL up through the other two so I can do cleanup in the UI and BLL if a database call fails. I also need to be able to trap exceptions originating locally in the BLL and UI layers.

I haven't dealt with n-Tier exception handling before and I am interested in what is considered a best practice approach to this.

As a starting point, I have attached a code snippet with a very basic first attempt. I have a custom exception defined for each call level so I can trap  and rethrow those separately from exceptions originating locally. If an exception occurs locally it is rethrown as a new custom exception defined for that level.


Private Class CallOneException
        Inherits Exception
End Class
 
Private Class CallTwoException
        Inherits Exception
End Class
 
 
Private Sub BaseCall()
	Try
	CallOne
	Catch CallOneEx As CallOneException
        Catch CallTwoEx As CallTwoException
	Catch Ex As Exception
        Finally
        End Try
    End Sub
 
Private Sub CallOne()
	Try
	CallTwo
        Catch CallTwoEx As CallTwoException
	Throw
        Catch Ex As Exception
        Throw New CallOneException       
	Finally
        End Try
    End Sub 
 
Private Sub CallTwo()
        Try
        Catch ex As Exception
        Throw New CallTwo Exception
        Finally
        End Try
    End Sub

Open in new window

0
Comment
Question by:kkamm
  • 4
  • 2
  • 2
  • +2
10 Comments
 
LVL 6

Accepted Solution

by:
openshac earned 600 total points
ID: 24260752
kkamm,

This sort of question comes up a lot, there is no definitive answer as such.
However here are some articles which should give you some answers to your question.

http://stackoverflow.com/questions/723690/error-handling-in-3-layered-architecture

http://forums.asp.net/p/1370018/2862386.aspx

http://bytes.com/groups/net-c/234559-error-handling-display-n-tier-design

Remeber the GUI should have no references to anything in the datalayer.  So if you get a data layer error, let the business layer interpret that and decide whether to handle it or how to push it to the GUI.

There's nice answer by jim cakalic here:
http://www.experts-exchange.com/Programming/Theory/Software-Design/Q_24201049.html
0
 
LVL 70

Assisted Solution

by:Éric Moreau
Éric Moreau earned 150 total points
ID: 24260899
0
 
LVL 1

Author Comment

by:kkamm
ID: 24261518
Thanks for the links. It seems like this is a pretty common issue.

>Remember the GUI should have no references to anything in the datalayer.  So if you get a data layer >error, let the business layer interpret that and decide whether to handle it or how to push it to the GUI.

My DAL CRUD routines currently return either booleans or data objects to indicate the status of an operation, but not any exception info, which is what I am looking to do. Any knowable DAL exceptions, such as an offline server, are handled by conditionals locally and not by exception code. I will probably take care of detailed logging, cleanup etc. locally, but I still need to give the user some indication of what kind of error occurred.

 Is it still considered bad form to pass just the error message up the call stack?


0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 6

Expert Comment

by:openshac
ID: 24261652
I guess what I was refering to was your line in BaseCall :
Catch CallTwoEx As CallTwoException

>>Is it still considered bad form to pass just the error message up the call stack?
Certainly not, you should never just handle unexpected errors blindly.  That would mean you are allowing your code to run in an unexpected state.

But if as you say the DB server is offline, then by all means get a friendly error to the GUI (it doesn't need to know the stack trace etc, the BL could log this).
0
 
LVL 1

Author Comment

by:kkamm
ID: 24262962
So the convention of rethrowing an exception up to the caller is considered an ok practice, as long as the actual handling (cleanup,etc.) is done at the originating layer?

Part of the complexity of this for me is having to do related cleanup through the call chain. If a user updates an item in the UI, and there is a problem with the server, then the app won't know this until it attempts a DAL operation. In the meantime, the grid view has an updated row, as well as the collection it is bound to. What I am doing currently is holding off on any updates being finalized in the UI and BLL until the call to the DAL is completed successfully. If it isn't, and an exception is thrown, then the BLL and UI updates are cancelled before being committed.
0
 
LVL 12

Assisted Solution

by:marklorenz
marklorenz earned 150 total points
ID: 24265137
This is what has worked well for me in the past:
- Start and commit/rollback transactions at the interface level (between the view and the model)
- When an exception happens, convert or wrap it in a "standard" exception for your project. I find that you don't need a ton of exception classes, but rather need some flexible ways of communication "up" what is wrong (e.g. standard text with values filled in according to what's wrong) as well as the original error. Also, very important: log details where it is detected and, depending on the type of issue, send an email to a support email address (e.g. on a beeper).
- At the higher levels (such as UI/view), tell the user something useful on how to proceed (like "You action did not succeed. Support has been notified. Please refresh your page and try again" or some such).

HTH, Mark
0
 
LVL 1

Author Comment

by:kkamm
ID: 24273977
Do you define all your custom exceptions in a separate project and then reference that from the 3 layers? Right now, I have an exception class for each layer, but I think I would be better off grouping these together into a separate project.

 I would like to define separate exceptions for each layer, but some of those exceptions are going to be rethrown from DAL to BLL and up to the UI, so each layer has to be able to reference the type. Ultimately, the UI is going to notify the user for every exception, so it will be catching each custom exception type one way or the other. The BLL and DAL will simply log and rethrow their exceptions, as I do not want either of those to have UI thread access (modal dialogs,status bars,etc.)

Also-do you separate your custom exceptions according to the exception domain? (i.e. MySQLException,MyNetworkException,etc.)

0
 
LVL 39

Assisted Solution

by:abel
abel earned 600 total points
ID: 24341236
> so each layer has to be able to reference the type.

no, not really. That's what the InnerException is for. You should not need to reference that in an outer class. If you ever see a complex exception, you are faced with the outer exception, and you can reference the innerexception objects without needing to know their types beforehand.

There are some excellent reads on exceptions best practices. Not all give the same advice I would (which is probably why it is such an often-debated subject) but here are some that are definitely worth reading:

Good list of do's and don'ts: http://www.eggheadcafe.com/articles/20060612.asp

Excellent (5 stars if I had them) article, along the same line, better examples: http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx. Please do read the parts on creating your own exceptions.

A simple hint on "throw" vs "throw ex": use the first: http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx

Excellent reading on the "when" part about exceptions (also follow the referred link): http://srtsolutions.com/blogs/billwagner/archive/2006/08/31/best-practices-for-exception-management.aspx
0
 
LVL 1

Author Comment

by:kkamm
ID: 24384313
There is a lot of good info in the links provided. It tells me that I definitely do not want to pass exceptions as return values, which I was considering.
0
 
LVL 39

Expert Comment

by:abel
ID: 24384374
> There is a lot of good info in the links provided.

Tx. If you like the answers (good), why do you do a low-grade then? Please consider the guideline about the 10pts must principle at EE. In short B or C should only be used in rare situations where you still yearn for more information but you don't get it, or the information is just not good and the expert does not follow up with something better.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

One of the most frequent problems a "newbie" developer may encounter is having to deal with different data formats. One for all: THE DATE We, as humans, need to "see" a date and then interpret it (much of the times this is an automatic operation)…
What is Waterfall Model? Waterfall model is the classic Software Development Life Cycle method practiced in software development process. As the name "waterfall" describes, this development is flowing downwards steadily like waterfall, i.e., procee…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Screencast - Getting to Know the Pipeline
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question