Wrapping an Exception
A frequently required exception-handling task is wrapping one exception with a different exception. Wrapping an exception creates a new exception of a defined type and sets the original exception as the InnerException object of the new exception. Use the wrapping capability in situations where the original exception type must be mapped to a new exception type for use by other tiers within the architecture of the application. You can encapsulate and interpret details of the underlying layer's original exception without losing any details about that exception. You can wrap the original exception either in an existing exception type or in a custom exception type that you create. The following explains a situation when you would want to wrap an exception:
- A business service named Update Customer calls a data layer service.
- The data layer service fails and throws an exception. This could be any one of many exceptions that indicate that the update failed. Some sets of these exceptions indicate that recovery may be possible with a retry (for example, if a record is locked) while others are non-recoverable (for example, if there is a concurrency violation or a dirty record).
- The exception handler maps and wraps these sets of exceptions into two exception types, RecoverableUpdateException and FatalUpdateException.
- The business service handles the exception based on the wrapping type and takes the appropriate action, even though it is insulated from detailed knowledge of the underlying failure.
Usage Notes
Consider the following information when you configure the application block to use a wrap handler:
- Typically, exceptions should be wrapped after they are logged in their original state.
- To help in the management and tracking of exceptions, the application block generates a HandlingInstanceID object that you can use to map to the original exception. To use the HandlingInstanceID, you must include the {handlingInstanceID} token in the exception message that is in the configuration file. The HandlingInstanceID is of type GUID. For more information, see Assisting Support Staff.
- If the post handling action is set to ThrowNewException, the exception thrown by the application block is the final exception that results from running the entire chain of handlers. For example, if the chain specifies that exception A is to be wrapped with exception B, and a later handler replaces exception B with exception C, the application block throws exception C when the post handling action is set to ThrowNewException.
- If the post handling action is set to NotifyRethrow, the application block returns true to the calling code. This allows the code to throw the original exception.
- Application code should always check the return value instead of assuming that it is the same value as the configured value. Even if the configuration data changes, if the application code checks the return value, the application code will function correctly and will not need to be modified.
- The exception type used to wrap another exception must have a constructor that accepts two parameters: a string and an exception object. This means that you must provide this constructor overload for all custom exception types that are used to wrap other exceptions.
- 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.