3

Is there any way of overriding the error message logged by Elmah without duplicating it?

I have a custom exception class:

public class BusinessException : Exception
{
    // detailed error message used for logging / debugging
    public string InternalErrorMessage { get; set; }

    public BusinessException(string message, string internalMessage)
        :base(message)
    {
        InternalErrorMessage = internalMessage;
    }
}

From the code, i throw an exception like this:

string detailedErrorMessage = string.Format("User {0} does not have permissions to access CreateProduct resource", User.Identity.Name);
throw new BusinessException("Permission denied", detailedErrorMessage);

When Elmah logs the error, it only logs Permission denied message. However, i need to log the InternalErrorMessage property of the exception instead.

I've tried to create a custom HandleErrorAttribute to do this, but this duplicates the exceptions logged:

public class ErrorHandleAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled == true)
            return;

        Exception exception = filterContext.Exception;

        BusinessException businessException = exception as BusinessException;
        if (businessException != null)
        {
            ErrorSignal.FromCurrentContext().Raise(new Exception(businessException.InternalErrorMessage, exception));
        }
    }
}

enter image description here

Catalin
  • 11,503
  • 19
  • 74
  • 147

2 Answers2

2

I think your issue might be here:

    if (businessException != null) {
        ErrorSignal.FromCurrentContext().Raise(
            new Exception(businessException.InternalErrorMessage, exception));
    }

When you create a new exception rather than something like this:

    if (businessException != null) {
        ErrorSignal.FromCurrentContext().Raise(businessException));
    }

I have this done the code for one of my sites and can see if I can recreate your issue later today (assuming this does not work). I think this is the SO post that helped me implement: How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?

Edit:

Re-reading your question and the other answer I realize I was trying to solve your attempted correction and not the actual problem. Have you tried something like this solution which is only a slight deviation from your current attempt:

public override void OnException(ExceptionContext filterContext) {
    if (filterContext.ExceptionHandled == true) {
        return;
    }
    Exception exception = filterContext.Exception;

    BusinessException businessException = exception as BusinessException;
    if (businessException != null) {
        var customEx = new Exception(
            businessException.InternalErrorMessage, new BusinessException());
        ErrorSignal.FromCurrentContext().Raise(customEx);
        return;
    }
}

Check that the InternalErrormessage is returning what you expect, and I expect that forcing a return here will prevent the exception from being logged twice. Otherwise it is essentially what you had done.

Community
  • 1
  • 1
Matthew
  • 9,851
  • 4
  • 46
  • 77
  • Just opened my project and I did not write the custom handler. Let me know if this was not your problem and I will try and replicate on the weekend. – Matthew Mar 07 '14 at 23:07
  • return would be a good idea, but the `ErrorHandleAttribute` is used also to set the result type (create a JSON error object to return to the user) – Catalin Mar 13 '14 at 07:00
  • Are you getting the error you want to see now though (so duplicated but the message you want?) – Matthew Mar 13 '14 at 14:40
  • No, unfortunately i am still getting the inner exception message, and the messages are duplicated – Catalin Mar 14 '14 at 07:11
0

I suspect you'll need to create your own errorlog implementation to log anything other than the standard properties. This shouldn't be too difficult.

Using the SqlErrorLog as an example, you only need to override the log method & put in your own logic to modify what the Error class contains before calling the base implementation.

Using what @Matthew has also said will stop you logging the exception twice.

All the source code is here

Simon Halsey
  • 5,459
  • 1
  • 21
  • 32