In previous articles, we covered Logging Application Block In Microsoft Enterprise Library 6.0.

Introduction

Exception handling is one of the most important tasks in any application. Many applications either do not handle applications or they handle it in an Adhoc manner.
In this section, we will see how we can use the readymade exception handling block so that we need not code, and build error handling routines from scratch.
How
We have to install Enterprise Library – Exception Handling Application Block from NuGet Packages.
.net
.net
Install Enterprise Library – Exception Handling Application Block Logging Handler from NuGet Packages to log the exceptions that are going to be thrown by the application.
.net
.net
Microsoft Enterprise Library Configuration Tool
This tool will be used to configure different blocks for the application. Now, we need to install the Microsoft Enterprise Library from the below URL by following the installation instructions.
Microsoft Enterprise Library 6
.net
As in this article, we are just going to discuss the Exception Application Block, we will now configure the exception handling configuration details for our application.
Please follow the configuration steps below
Right-click on the App.config >> Open with Enterprise Library Application Block Console. If it is not available in the list, you can add it manually by clicking on the "Add" button.
.net
.net
.net
.net
.net
.net
.net
.net
Using Exception Handlers
The Exception Handling Application Block is designed to support the typical code contained in catch statements in application components. Instead of repeating this code (such as - logging exception information), throughout the identical catch blocks in an application component, the application block allows developers to encapsulate this logic as reusable exception handlers.
Exception handlers are .NET classes that encapsulate exception handling logic and implement the Exception Handling Application Block interface named IExceptionHandler.
The Exception Handling Application Block includes five exception handlers:
In this article, we are going to cover Wrap, Replace, and Logging Exception Handler.
.net
.net
.net
.net
.net
In the same way, we can configure the settings for Replace Handler also. The total configuration will look something like the image shown below:
.net
Now, we are done with our configuration for the Exception Handling Block; and, we are going to configure the Logging Application Block here to log the exceptions that are going to be thrown by our application.
I am not going to explain regarding configuring Logging Application Block here as we have already covered that in my previous article. Click here to have a look at the Logging Application Block.
After configuring the Exception Handling and Logging Block, the configuration tool will look as below.
.net
All the above configuration will generate the below sections in our App.config.
You can directly add the below configuration blocks to your App.config under <configuration> section if you don’t want to configure through the configuration console.
  1. <configSections>
  2. <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  3. <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  4. </configSections>
  5. <loggingConfiguration name="" tracingEnabled="false" defaultCategory="General" logWarningsWhenNoCategoriesMatch="false">
  6. <listeners>
  7. <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" fileName="RollingFlatFile.log" footer="----------------------------------" formatter="Text Formatter" header="" rollInterval="Day" traceOutputOptions="DateTime, Timestamp" filter="All" />
  8. <add name="Event Log Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" source="Application" formatter="Text Formatter" log="Application" machineName="." traceOutputOptions="None" />
  9. </listeners>
  10. <formatters>
  11. <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="Timestamp: {timestamp(local)}{newline}
  12. Message: {message}{newline}
  13. Category: {category}{newline}
  14. Priority: {priority}{newline}
  15. Severity: {severity}" name="Text Formatter" />
  16. </formatters>
  17. <categorySources>
  18. <add switchValue="All" autoFlush="true" name="General">
  19. <listeners>
  20. <add name="Rolling Flat File Trace Listener" />
  21. <add name="Event Log Trace Listener" />
  22. </listeners>
  23. </add>
  24. </categorySources>
  25. <specialSources>
  26. <allEvents switchValue="All" name="All Events">
  27. <listeners>
  28. <add name="Rolling Flat File Trace Listener" />
  29. </listeners>
  30. </allEvents>
  31. <notProcessed switchValue="All" name="Unprocessed Category">
  32. <listeners>
  33. <add name="Rolling Flat File Trace Listener" />
  34. </listeners>
  35. </notProcessed>
  36. <errors switchValue="All" name="Logging Errors & Warnings">
  37. <listeners>
  38. <add name="Rolling Flat File Trace Listener" />
  39. </listeners>
  40. </errors>
  41. </specialSources>
  42. </loggingConfiguration>
  43. <exceptionHandling>
  44. <exceptionPolicies>
  45. <add name="ExceptionHandling">
  46. <exceptionTypes>
  47. <add name="Base Exception Handler" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">
  48. <exceptionHandlers>
  49. <add name="Base Wrap Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WrapHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="Exception occurred in application." wrapExceptionType="System.ApplicationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  50. <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" logCategory="General" eventId="9000" severity="Error" title="ExceptionHandlingBlock" formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="5" />
  51. </exceptionHandlers>
  52. </add>
  53. <add name="DivideByZero Exception Handler" type="System.DivideByZeroException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">
  54. <exceptionHandlers>
  55. <add name="DivideByZero Replace Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="Divide By Zero Exception Occurred." replaceExceptionType="System.ApplicationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  56. <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" logCategory="General" eventId="9000" severity="Error" title="ExceptionHandlingBlock" formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="5" />
  57. </exceptionHandlers>
  58. </add>
  59. <add name="FileNotFound Exception Handler" type="System.IO.FileNotFoundException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">
  60. <exceptionHandlers>
  61. <add name="FileNotFound Replace Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="FileNotFound Exception Occurred." replaceExceptionType="System.ApplicationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  62. <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" logCategory="General" eventId="9000" severity="Error" title="ExceptionHandlingBlock" formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="5" />
  63. </exceptionHandlers>
  64. </add>
  65. </exceptionTypes>
  66. </add>
  67. </exceptionPolicies>
  68. </exceptionHandling>
Now, the configuration part is done for the Exception Handling block, which can be used throughout the application level.
Let’s build a sample console application to experience the functionality.
ExceptionHandler Class
  1. using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
  2. using Microsoft.Practices.EnterpriseLibrary.Logging;
  3. using System;
  4. namespace ExceptionHandlingBlock
  5. {
  6. /// <summary>
  7. /// Purpose for this type is to ease the handling of the exception handling.
  8. /// </summary>
  9. public static class ExceptionHandler
  10. {
  11. #region Static Variables
  12. private static LogWriter logWriter;
  13. private static readonly ExceptionPolicyFactory _exceptionPolicyFactory;
  14. private static readonly ExceptionManager _exceptionManager;
  15. #endregion
  16. #region Constructor
  17. static ExceptionHandler()
  18. {
  19. logWriter = new LogWriterFactory().Create();
  20. Logger.SetLogWriter(logWriter, false);
  21. _exceptionPolicyFactory = new ExceptionPolicyFactory();
  22. _exceptionManager = _exceptionPolicyFactory.CreateManager();
  23. }
  24. #endregion
  25. #region Static Methods
  26. /// <summary>
  27. /// Performs the handling of an application towards the configured policy.
  28. /// <param name="ex">Exception to handle.</param>
  29. public static void HandleException(Exception ex)
  30. {
  31. Exception exceptionToThrow = null;
  32. //The HandleException method will return true if the exception should be (re-)thrown.
  33. if (_exceptionManager.HandleException(ex, "ExceptionHandling", out exceptionToThrow))
  34. {
  35. if (exceptionToThrow == null)
  36. {
  37. Console.WriteLine(ex.Message);
  38. Console.ReadKey();
  39. }
  40. else
  41. {
  42. Console.WriteLine(exceptionToThrow.Message);
  43. Console.ReadKey();
  44. }
  45. }
  46. }
  47. #endregion
  48. }
  49. }
Executer Class
  1. using System;
  2. using System.IO;
  3. namespace ExceptionHandlingBlock
  4. {
  5. class Executer
  6. {
  7. static void Main(string[] args)
  8. {
  9. BaseException();
  10. //DivideByZeroException();
  11. //FileNotFoundException();
  12. }
  13. public static void BaseException()
  14. {
  15. try
  16. {
  17. string x = null;
  18. int a = 10;
  19. Console.WriteLine(int.Parse(x) + a);
  20. }
  21. catch (Exception ex)
  22. {
  23. ExceptionHandler.HandleException(ex);
  24. }
  25. }
  26. public static void DivideByZeroException()
  27. {
  28. try
  29. {
  30. int x = 5;
  31. int y = 0;
  32. int z = x / y;
  33. }
  34. catch (DivideByZeroException ex)
  35. {
  36. ExceptionHandler.HandleException(ex);
  37. }
  38. }
  39. public static void FileNotFoundException()
  40. {
  41. try
  42. {
  43. // Read in non-existent file.
  44. using (StreamReader reader = new StreamReader("TextFile1.txt"))
  45. {
  46. reader.ReadToEnd();
  47. }
  48. }
  49. catch (FileNotFoundException ex)
  50. {
  51. ExceptionHandler.HandleException(ex);
  52. }
  53. }
  54. }
  55. }
Let me explain a bit about the above code blocks.
Once you execute the application, it will create the Log file in the debug folder as no specific path is mentioned for the file in the configuration and log the message in Windows Event Log.
.net
Executing the BaseException Method
Windows Event Log
.net
Executing the DivideByZeroException Method
Windows Event Log
.net
Executing the FileNotFoundException Method
Windows Event Log
.net

Resources

Conclusion

The best part of the Exception Handling Application block is that you can change policies and handlers on the fly without compiling the code. You can also change the error logging source from event viewer to file or email. I have attached the sample application. Just download it and experience the Exception Handling functionality in Microsoft Enterprise Library 6.0.
I hope you have enjoyed this article and I am sure if you use this block properly, you can have a very stable, efficient, and flexible error handling framework.
In the next article, we will cover the Data Access Application Block in Microsoft Enterprise Library 6.0.
Happy Coding!!!