Search code examples
c#exceptionelmah

elmah.axd custom exception message with stacktrace of child throwed exception in C#


What I want to achieve is to show a custom exception Type and Error message in elmah.axd table but with the original stacktrace of a child throwed exception.enter image description here This is just an example of a nested try catch that match my needs:

// custom exception constructor
public MyCustomException(string customMsg, Exception expt):base(customMsg,expt)

// my test case
try{
    try{
        //_context.saveChanges(); --> this will generate an exception
        // but for this example we'll throw the following
        throw new IndexOutOfRangeException();
    }
    catch (Exception e){
        // here elmah will print in the Type column "IndexOutOfrange" and in the Error column the message: "Index was outside the bounds of the array. Details..."
        ErrorSignal.FromCurrentContext().Raise(e);

        // now I throw a custom exception with the original stacktrace of "IndexOutOfrangeException"
        throw new MyCustomException("Message to see in elmah 'Error' column", e)
    }
}
catch(MyCustomException cex){
    // here elmah will also print in the Type column "IndexOutOfrange" and in the Error column the message: "Index was outside the bounds of the array. Details..." with the original stacktrace
    ErrorSignal.FromCurrentContext().Raise(cex)

    // my expectation would be to print in the Type column "MyCustomException" and in the Error column the message: "Message to see in elmah 'Error' column Details..." with the original stacktrace
}
catch(Exception ex){
    // some code here
}

Am I doing something wrong or it's just not possible what I want?


Solution

  • ELMAH always uses the base exception to generate the Type and Error fields. This is the best (IMO) way of doing it since the base exception will always be the original cause of the error. This explains why you get the type and message of the IndexOutOfRangeException logged in ELMAH.

    There's a small "hack" to resolve this if you switch to using the Log method:

    try{
        try{
            throw new IndexOutOfRangeException();
        }
        catch (Exception e){
            throw new MyCustomException("Message to see in elmah 'Error' column", e)
        }
    }
    catch(MyCustomException cex){
        var error = new Elmah.Error(cex);
        // Type and Error will now have the values of `IndexOutOfRangeException`
        error.Type = cex.GetType().FullName;
        error.Message = cex.Message;
        // I manually updated the values from `MyCustomException`
        ErrorLog.GetDefault(HttpContext.Current).Log(error);
    }
    catch(Exception ex){
        // some code here
    }
    

    I tested this locally and both Type and Error get the value from the outer exception.