Exception Handling Techniques for ASP.NET Application with Multiple Layers

M

metsys

We have an ASP.NET 2.0 (C#) application that is divided into multiple
layers. The multiple layers come from having a web project and 2 different
class library projects in the same solution.

I'm having difficulties figuring out the best way to handle (catch)
exceptions in the different layers and then propagating those errors back up
through the call stack to ultimately display something to the end-user.
Note this is an intranet application to be used in-house by company
employees; it will not be a public Internet application.

See the code snippets below for an example of how we're handling things now.



ASP.NET Application
Web.config
<system.web>
<customErrors defaultRedirect="~/ErrorPages/ExceptionHandler.aspx"
mode="On" />
</system.web>


Global.asax
void Application_Error(Object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
// Formulate a message to write to the event log
...
}


Code-behind of .aspx page
System.Data.DataSet dsFacility = null;

try
{
// Do some other processing here
...

// Get the facility info from the database
dsFacility = BusinessRules.Facility.GetFacility();

// Do some other processing here
...
}
catch (System.Exception ex)
{
// Handle the exception, log it
...

// Throw the exception to be handled higher up the call stack
throw;
}



Business Rules class (this is a separate class library project)
public static class Facility
{
public static System.Data.DataSet GetFacility()
{
// Get the facility information
System.Data.DataSet dsFacility = null;

try
{
// Do some other processing here
...

// Get the facility info from the database
dsFacility = DataAccess.Facility.GetFacility();

// Do some other processing here
...
}
catch (System.Exception ex)
{
// Handle the exception, log it, etc.
...

// Throw the exception to be handled higher up the call
stack
throw;
}

// Rows found, return the queried dataset
return dsFacility;
}
}



Data Access class (this is a separate class library project)
public static class Facility
{
public static System.Data.DataSet GetFacility()
{
// Define and initialize local variables
string sqlCommand = "";
System.Data.SqlClient.SqlConnection scFacility = null;
System.Data.SqlClient.SqlDataAdapter sdaFacility = null;
System.Data.DataSet dsFacility = null;

try
{
// Create and populate the local variables
sqlCommand = "SELECT * FROM Facility ORDER BY FacilityName";
scFacility = new
System.Data.SqlClient.SqlConnection(DatabaseConfiguration.RegPerfectDbConnec
tionString);
sdaFacility = new
System.Data.SqlClient.SqlDataAdapter(sqlCommand, scFacility);
dsFacility = new System.Data.DataSet();

// Fill the dataset
sdaFacility.Fill(dsFacility, "Facility");
}
catch (System.Exception ex)
{
// Handle the exception, log it, etc.
...

// Throw the exception to be handled higher up the call
stack
throw;
}
finally
{
// Close the connection to the database
scFacility.Close();
scFacility.Dispose();
}

// Return the information
return dsFacility;
}
}



I'm not even sure of what to ask at this point. But, is this a good way of
handling things? Is there a better way?

It just doesn't seem to be working as expected. For example, if an
exception is thrown in the data access class, it is caught and logged. Then
the code returns to the business rules class in the exception handler, but
now the exception is undefined. And then trying to throw this undefined
exception seems to be throwing an exceptions itself (I think. It gets kind
of confusing at this point.). Finally, we get back to the web application
and catch some exception, which may or may not even be the right thing.

It's very convoluted. That's why I'm thinking that there's got to be a
better way.

Hope this all makes sense. Any help/advice is greatly appreciated. Please
let me know if I can provide other information.

Regards.
 
A

Andrew Robinson

1. On thing that I would suggest is that you should almost never trap
anthing but an ApplicationException or an exception that inherits from it.
Change your System.Exceptions.

2. If you are only logging the exception in your lower level classes, why
not just allow it to bubble up?

3. Trap all exceptions in your Global exception handler at the top of the
chain. For this do use the System.Exception that you have.

4. Make sure you also log inner exceptions!
 

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