3

In enterprise library I wasn't getting enough detail put into my logs, so I started writing this handler to pull out of the exception specific properties and add them to the message string:

[ConfigurationElementType(typeof(CustomHandlerData))]
public class ExposeDetailExceptionHandler : IExceptionHandler
{
    public Exception HandleException(Exception exception, Guid handlingInstanceId)
    {
        if (exception is System.Net.WebException) 
            return ExposeDetail((System.Net.WebException)exception);
        if (exception is System.Web.Services.Protocols.SoapException) 
            return ExposeDetail((System.Web.Services.Protocols.SoapException)exception);

        return exception;
    }

    private Exception ExposeDetail(System.Net.WebException Exception)
    {
        string details = "";
        details += "System.Net.WebException: " + Exception.Message + Environment.NewLine;
        details += "Status: " + Exception.Status.ToString() + Environment.NewLine;

        return new Exception(details, Exception);
    }

    private Exception ExposeDetail(System.Web.Services.Protocols.SoapException Exception)
    {
        //etc
    }
}

(As as aside is there a better way of picking which version of ExposeDetail gets run?)

Is this the best or accepted way to log these details, my initial thought is that I should be implementing an ExceptionFormatter but this seemed a lot simpler.

Stephen Turner
  • 7,125
  • 4
  • 51
  • 68
  • Did you try just logging ex.ToString()? That should display everything the exception wants to display. – John Saunders Nov 27 '11 at 07:06
  • Exception.ToString() only displays the type, the message, the stack trace, and any InnerExceptions (recursively). It does not display properties specific to a WebException like Status and Response. – hypehuman Jan 22 '16 at 20:55

2 Answers2

2

Use Exception.Data. You can collect any extra details you want to log at the point the exception is first caught and add them into Exception.Data. You can also add other information that wasn't part of the original exception such as the Url, http headers, ...

Your exception logging code can then pick up Exception.Data and add all that information to the log.

You don't need to wrap the exception nor do you need to lose any of the call stack when you handle it this way. Use throw to rethrow the original exception, catch it again further up the stack, add more context to the .Data on it and so on out until you get to your exception handler.

Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
1

I think you are right: an ExceptionFormatter is probably a better way.

I would use the extended properties to add your details. I don't think that it is any more complicated than a handler.

E.g.:

public class AppTextExceptionFormatter : TextExceptionFormatter
{
    public AppTextExceptionFormatter(TextWriter writer, 
             Exception exception, 
             Guid handlingInstanceId)
        : base (writer, exception, handlingInstanceId) 
    {
        if (exception is System.Net.WebException) 
        {
            AdditionalInfo.Add("Status", ((System.Net.WebException)exception).Status.ToString());
        }
        else if (exception is System.Web.Services.Protocols.SoapException)
        {
            AdditionalInfo.Add("Actor", ((SoapException)exception).Actor);
        } 
    }
}
Randy Levy
  • 22,566
  • 4
  • 68
  • 94