Where do you handle your exceptions?

L

Liming

Hi,

In a typical 3 tier model (view layer, busines layer and data access
layer) where do you handle your exceptions? do you let it buble up all
the way to the .aspx pages or do you handle it in your business layer
and/or data access layer?

suppose in my data access layer, I provide try and catch, log the
exception and re-throw it back to business layer, then in yoru business
layer, what do you do? throw it back to the code behind or you handle
it right there?

Right now, here is my workflow.

1) I handle my exceptions in my data access layer, log it and return
an integer value back to top, so say for a Insert method, I return "0"
for failed insert and any postive integer (which will be primary key of
the the inserted database row) up to business layer.
2) Business layer then use this integer value to handle the approriate
actions (for example, if row is inserted, email to somebody) and return
the same value back to codebehind.
3) Codebehind checks if it's a 0 or a positive integer, if 0, then
display a message to user "insert failed, please contact yoru admin"

I have a feeling this is a bad pratice, but not sure why. Just then I
had this problem where two pages (1 user page and 1 admin page) are
accessing the same insert method. The user page just need to say "Error
occured while inserting, please contact your admin" (admin would in
term check the log files) and in the admin page however, we want to
directly tell them exactly what the exception is which in this case,
bubble up the exception would seem approriate.

So I realized my way of handling exception is hugely flawed, I'm
wondering how you guys handle your exceptions in your asp.net tierd
design?

Thanks a lot.
 
P

Peter Bradley

No, it's not so bad at all. At least it's been given some thought.

Just for your interest, here's what we do:

* We define our own exceptions. Their names are as self-documenting as
possible
* Data Access layer: Any exceptions are returned to the business layer,
with a message providing whatever detail our analysis has shown to be
needed.
* Business layer (dealing with exceptions from the data acess layer or
exceptions thrown during its own processing): The explicit message is
written to an application event log and the exception is passed back to the
presentation layer (this means that you have to set up Web.config correctly
to return remote exceptions) with a new, more user-friendly message..
* Presentation layer: The exception is either caught immediately and dealt
with (if the error is recoverable), providing the user with the
user-friendly message in a "Messages" area on our pages; or the exception is
allowed to bubble up and be caught by the Application_Error handler. The
Application_Error handler redirects the user to a generic error page, where
the user-friendly message is displayed and the user is given appropriate
instructions as to what to do next (either restart or contact our HelpDesk)

The main point is that *all* exceptions are caught. The user should never
be presented with the default ASP.NET error page. I say, "Should", because
I recognise that we are not perfect; but the times that we fail are due to
pretty obscure events - and are corrected as soon as they come to light
(hopefully, before the application goes live, but ...)

:)

Our architecture has the Web server in a DMZ. It is not on any domain. The
application server and the database server are both on the same domain and
use trusted connections. There is a service/services running on the
applicaiton server that hosts the business layer remote objects. We use
almost exclusively SingleCall SAOs. The data layer uses, almost
exclusively, stored procedures to interact with the database.

I think that just about covers it.

There are, of course, situations where errors are trapped without the use of
exceptions. In these cases, the return values will be tested to detect the
presence or absence of an error condition (a method returns null when an
object is expected). In these cases, the calling method will either deal
with the error condition - if it can - or will throw an exception of a
suitable type, with a suitable message.

I'm sure that others will have other, perhaps more constructive input to
give.

HTH


Peter
 
B

Bike

Greetings,

ASP.NET 2.0 automatically logs any unhandled exceptions in event log (for
..NET 1.x you can log Exceptions in Application_Error method in Global
class), so I rely on that for logging. I also set <customErrors
mode="RemoteOnly" defaultRedirect="myerrorpage.html" /> the web.config in
production server, and <customErrors mode="Off" /> in development. I rely on
try/finally to commit/rollback transactions. So usually I don't have any
exception handling code in business layer code, data access layer code or
aspx pages. Sometimes I do extra handling in Application_Error method of the
global class (such as sending notification of the exception or logging).

Of course there are cases where I use try..catch in business layer or aspx
page, but these are not frequent.
 
K

Kevin Spencer

That is a tough question. It depends upon your overall requirements, as well
as the tier in which the Exceptions are thrown, and whether and how they may
be handled gracefully.

In an ASP.Net application (or any other UI application), you almost
certainly don't want an Exception to be thrown in the User Interface. You
want to handle the Exception gracefully, at the very least informing the
user that an Exception has occurred, and what the user should do next.
However, in your business layer, you want to throw unhandled Exceptions,
that is, Exceptions that cannot be recovered gracefully from in your code
somehow, because these business classes may be re-used by a variety of
applications, each of which may need to handle Exceptions differently. So,
it should be up to the application and/or interface layer to determine what
to do with unhandled Exceptions, and they should be bubbled up.

But you may also, depending upon the circumstances, want to provide to the
developer(s) of the application as much information as possible about the
exception, so that they may be able to diagnose and correct the problem.
This may involve (again, depending upon the circumstances) any of the
following:

Event Logging in the System Event Log
Text File Logging in the File System
Network notifications/alerts
Emailing the developers with the information
Uploading Exception information to a web service or other network service,
to be stored in a database.

This may also be dependent upon the phase of development for the
application, whether it is being written/debugged, tested, or
fully-deployed.

For example, most Microsoft applications will attempt to upload Exception
information to Microsoft, if the user allows it, and almost always log
information about the Exception in the local System Event Log. My company
runs a Windows Service that runs constantly, 24 hours a day, unattended.
This service also logs Exception data in the System Event Log. But in
addition, it has the capability to email a configurable list of recipients
with Exception information immediately when the Exception occurs, so that we
can take action immediately to prevent down-time of the Service.

Again, if you want to notify the developer(s) about the Exception, you will
want to include as much information as possible. OTOH, if you are
distributing a class library or application, you may not necessarily want or
be able to send all of that information.

Our solution is to use a set of global Exception-Handling methods which can
(optionally) dissect various specific and generalized Exceptions to a minute
degree, and can be configured to work in various ways using application
configuration files. In addition, we have defined several global delegates
and an Exception-handling Interface that can be used in applications we
develop, so that each application may use these global methods in a
consistent manner, through a single method interface, but each in its' own
particular way, according to its assembly type, application type,
development phase, and environment.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

In case of Minimalism, break Philip Glass.
 
S

sloan

My recommendations are:


IN the DAL

try
{
}
finally
{

}

blocks. As opposed to try/catch/finally blocks.

...

In the BAL.

Create your own exception(s).

class AccountOverdrawnException
stuff like that.

Now, it depends on what you want to do.
If you want your user to see "friendly messages", then you can catch a
"geeky" exception, and throw the custom exception.

EX:

class (BAL).EmployeeController

public IList GetAllEmployees

try
{
//do stuff here to create an IList of employees, calling your DAL
object.
}
catch ( System.Data.Common.DbException dbex )
{

throw new CustomFriendlyException ("The database is currently
unavailable, please try back again later." , dbex);

}
finally
{
//clean up stuff
}


However, if you're ok with the end user seeing nerdy exceptions, then don't
do this:

try
{

}
catch (Exception ex)
{
throw;// keep the stack trace.
//or
//throw ex;


}
this is just a waste of exceptional handling overhead.



Get rid of your "API" mentality. Where you pass back a 0 or 1 based on good
or bad results.

Finally,

Exceptions should be "exceptional".

Lets take a sample where you do a search for an employee by last name.

Ok, every once in a while , someone will enter a lastname that doesn't
exist.

Since you are expecting this from time to time, this is NOT "exceptional".

Handle this with null returns or something. or collections with zero items
in it.



class (BAL).EmployeeController

public IList GetAllEmployees
{
IList returnList = null;
try
{
//do stuff here to create an IList of employees, calling your DAL
object.
}

finally
{
//clean up stuff
}

return returnList;
}



then you can check for null

IList il = new EmployeeController().GetAllEmployees();
if(null!=il)
{
Console.Writeline ( il.Length.ToString() + " employees found " ;
}
else
{
Console.Writeline ( " No employees found " ;
}

...


Try to create custom exceptions for specific reasons, and don't get too
general with them.

public class AccountOverdrawnException
public class OrderMustHaveOrderDetailsException

......
 
L

Liming

wow, thanks a lot guys. Each one of your response gave me a better
picture as how I should design my application. I dont' know why I've
never put too much though into my exception handling achitecture, now I
realized it's more important than anything.

Thanks a lot guys, the information that each of you provided are
extremely invaluable to me, I can't describe how much I appreicate your
detailed responses.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top