Friday, August 05, 2005

Exception Management Strategy for N-tier Applications - Part III

This article is in continuation of my previous two posts on Exception Management Strategy for N-tier Applications. If you havent read them, please check Part I and Part II.

Code Snipped Continued ...

The sample code for wrapping an exception that is caused in the DAL is shown below:

try
{
// statements that access SQL Server
}
catch(SqlException sqlEx)
{
DataOperationFailedException dataOp = new DataOperationFailedException(sqlEx.Message,sqlEx);
dataOp.ErrorNumber = sqlEx.Number;
dataOp.SqlServerName = sqlEx.Server.ToString();
dataOp.ActionTaken = "";
dataOp.LogonUser = "";
dataOp.MstrStacktrace = sqlEx.StackTrace;
dataOp.ContextInfo = "MyNamespace.MyClass";

//Publish exception
ExceptionSQLPublisher.Publish(dataOp);

//Rethrow exception
throw dataOp;
}

The same way each module in the application can be wrapped suitably and the exception rethrown to above layer.

If the Web.config is configured to take to a specific error page, customized error messages for each type of exception cannot be shown.

So, the global.asax can be used to show customized error messages by finding the exception type that occured in the application. Here is the sample code:

protected void Application_Error(Object sender, EventArgs e)
{
Exception ex = Server.GetLastError().InnerException;
if(ex.GetType().ToString()== "Microsoft.ApplicationBlocks.
ExceptionManagement.DataOperationFailedException")
{
Response.Redirect(@"..\Error.aspx?Type=Data");
}
}

Exception Management Strategy for N-tier Applications - Part II

The previous article explained how important it is to have a Base exception class that can be used through out your application. In this article, let us examine what Exception Management stategy can be built for these Enterprise Applications. Let us suppose that the strategy we design must take care of the following points:
1. Any Exception raised in any of the Layers must be Logged. 2. The custom error page exposed by the Presentation Layer must also indicate some sort of context information (Either about the Module or some specific type of exception).

The second point is important because in a large application, its certainly difficult to track which module caused the exception. So if the custom error page contains some context specific information about the module that caused the exception, handling the exception would be easy.

So taking into consideration the above points, the following strategy can be designed:

1. Design specific custom Exception classes for each module that inherits from the MyAppBaseApplicationException class. Any exception that occurs in that module will be wrapped using this Exception class.

2. Any exception that occurs throught out your application will therefore be wrapped with the corresponding class and logged. Once the exception is logged, the isLogged flag of the base exception class will be set to true.This will avoid logging again on the higher layers.

3. The logging will happen to the database by default and if the database access fails, the error messages will be logged to Windows event log.

4. After the exceptions are logged the wrapped exceptions are then re-thrown to the next higher layer.

5. In the final layer, you will therefore have only the wrapped exceptions or the exception that occurs in the Presentation layer.

6. The custom error page in the Presentation layer can be shown with customised error messages for each module.

A sample custom exception class for the Data Access module is shown below:

public class DataOperationFailedException:MSTRBaseApplicationException
{
#region Fields
private int sqlErrorNumber;
private string sqlServerName;
private string storedProcName;
private int lineNumber;
#endregion

#region Properties

//Add properties to access the private variables
#endregion
}

Code Snippet Continued in my Next Post.