Propagating an Exception in Enterprise Library
A frequently required exception-handling task is to allow the original exception to propagate up the call stack unchanged. You may want to do this because the handlers only perform actions such as logging that leave the exception unchanged or because other actions, such as wrapping and replacing, have been turned off. For example, a routine within a business logic component may log exceptions at the point where they are detected. It then propagates that exception to the caller for additional handling.
Typical Goals
You want to let an exception propagate up the call stack unchanged after the exception handler chain completes. Your application has code in its catch blocks similar to the following.
Note:
The code does not include the FormatException and Logger.Log methods. These methods represent typical application code to create and log a formatted exception message.
C# Copy Code
catch(SomeException e)
{
// Exception handling code to be done before propagating.
string formattedInfo = FormatException(e);
Logger.Log(e);
throw e;
}
Visual Basic Copy Code
Catch e As SomeException
' Exception handling code to be done before propagating.
Dim formattedInfo As String = FormatException(e)
Logger.Log(e)
Throw e
End Try
QuickStart
For an extended example of how to use the Exception Handling Application Block to propagate the original exception, see the QuickStart walkthrough, Walkthrough: Propagating the Original Exception.
Solution
Configure the relevant exception type to use NotifyRethrow as its PostHandlingAction.
Propagating an Exception
The following procedure describes how to use the Exception Handling Block to propagate an exception.
To propagate an exception
Create an exception handling policy with the relevant exception types for your application. For more information, see Entering Configuration Information.
Configure the exception type. Specify the PostHandlingAction as NotifyRethrow. This causes the application block to return true to the application from the call to the HandleException method.
Modify your application code to execute the new policy when an exception occurs.
Examine the return value from the HandleException call. If the return value is true, execute a throw statement, as shown in the following code example.C# Copy Code
try
{
// Run code.
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "Propagate Policy");
if (rethrow)
{
// Throw original exception.
throw;
}
}
Visual Basic Copy Code
Try
' Run code.
Catch ex As Exception
Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Propagate Policy")
If (rethrow) Then
' Throw original exception.
Throw
End If
End Try
Usage Notes
If you use the Unity Integration approach to create instances of objects from the Exception Handling Application Block, you must use the non-static façade named ExceptionManager instead of the ExceptionPolicy class static façade.
Logging an Exception
A frequently required exception-handling task is to log the information associated with the exception. The Exception Handling Application Block, in conjunction with the Logging Application Block, lets you log formatted exception information in locations specified in the configuration file. For example, client applications typically log application information in the event log, while a server component of an e-commerce application may log exceptions in a database.
Typical Goals
You want to log an exception that occurred in one of the application layers before any other exception handling occurs. Your application has code in its catch blocks similar to the following.
Note:
The code does not include the FormatException and Logger.Log methods. These methods represent typical application code to create a formatted exception message and write it to a log destination.
C#
Copy Code
catch(SomeException e)
{
string formattedInfo = FormatException(e);
Logger.Log(e);
throw e;
} Visual Basic
Copy Code
Catch e As SomeException Dim formattedInfo As String = FormatException(e) Logger.Log(e) Throw e End Try
Solution
Designate the logging handler as the first handler in your policy's exception handling chain. The Exception Handling Application Block includes the logging handler.
QuickStart
For an extended example of how to log an exception, see the QuickStart walkthrough, Walkthrough: Logging an Exception.
Using the Logging Handler
To use the logging handler, you must configure the application exception policies and the Logging Application Block. You must then modify your application to use the appropriate exception handling policy.
To configure the application exception policies
- Use the configuration tools to create an exception handling policy for your application layer. For more information, see Entering Configuration Information.
- Specify the exception types to be processed and logged.
- Add the logging handler as the first handler for each exception type.
- Configure the logging handler:
- Enter the event ID.
- Enter the logging categories.
- Select the severity.
- Enter the title of the log entry.
- Select the formatter type name.
- Enter the priority.
- Add any additional exception handlers to be invoked after the logging handler.
To configure the Logging Application Block
- Add the Logging Application Block to your application configuration (adding a logging handler will automatically add the Logging Application Block to your application configuration). For more information, see Adding Application Code in the documentation for The Logging Application Block.
- Configure the Logging Application Block.
Modify Your Application
Modify your application code to execute the new policy when an exception occurs. The following code demonstrates how to do this. Substitute the name "Logging Policy" with the name of your own policy.
C#
Copy Code
try
{
// Run code.
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "Logging Policy");
if (rethrow)
throw;
} Visual Basic
Copy Code
Try ' Run code. Catch ex As Exception Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Logging Policy") If (rethrow) Then Throw End If End Try
Usage Notes
Consider the following information when you configure the application block to use a logging handler:
- Exceptions can be logged any time during processing; they do not have to be logged at the beginning of the event handling sequence. For example, you can log an exception after it is wrapped or replaced.
- The Exception Handling Application Block provides a logging exception handler that depends on the Logging Application Block. You can also incorporate custom logging functionality into your own exception handler to use instead of the Logging Application Block.
- The preceding code example uses a single generic handler for all managed exceptions (these are exceptions derived from the System.Exception class. Your own application could have other catch statements that call the HandleException method with different policies or that do not use the Exception Handling Application Block. The code in this example uses the policy name "Logging Policy" to emphasize its behavior. Generally, a policy name reflects the application layer or component that uses it, instead of its function. For example, a policy used by the data access layer would be named "Data Access Layer Policy."
- If you use the Unity Integration approach to create instances of objects from the Exception Handling Application Block, you must use the non-static façade named ExceptionManager instead of the ExceptionPolicy class static façade.
Changes to the Exception Handling Application Block
The following changes have been made to this version of the Exception Handling Application Block:
- Changed : When building a LoggingExceptionHandler, instead of creating a logging stack every time and ignoring it if the value for the use the default logger flag on the handler is set to true, the build process now uses the value for the flag in the configuration file to create the handler with either Logging.Writer (if true) or the result of creating a new stack (if false). The handler now only knows it has a writer; it does not know where it came from.
- Fixed : The DesignTime nodes for ExceptionHandlers are now handled correctly when using template-based messages. The variables are now accessed correctly when mapping an exception handler configuration object to the corresponding node and a valid configuration is saved.
- Fixed : Invalid XML generated by the XmlExceptionFormatter is fixed. Exception formatters now must include the HandlingInstanceId (which is generated on each exception handling request). The way the exception formatter includes HandlingInstanceId depends on the individual formatter. The XmlExceptionFormatter adds it as an attribute of the top-level Exception element; the TextFormatter adds it as the first line of text. An ID equal to Guid.Empty can be ignored.
The logging exception handler no longer adds the exception handling ID to the message to log. The formatter handles the ID. Exception Formatter types used with the logging exception handler must now implement a constructor with the parameters TextWriter, Exception, and Guid.
There is no backward compatibility support. Creators of custom formatters must update the formatters to be used with this version so that the handling instance ID is not lost because a formatter does not support it.