5

I am trying to implement global exception logging in web api and send a frienldy message to the user with that error ID, so he can come back to us with error Id so we can fix it. I am implementing both:

  • System.Web.Http.ExceptionHandling.ExceptionLogger
  • System.Web.Http.ExceptionHandling.ExceptionHandler

Here is my class that overrides ExceptionLogger abstract class:

public class GlobalExceptionLogger : System.Web.Http.ExceptionHandling.ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        LogMessage logMsg = new LogMessage();
        logMsg.ID = System.Guid.NewGuid().ToString();
        logMsg.MessageType = MessageType.ResourceServerAPI;
        logMsg.SenderMethod = context.Request.RequestUri != null ? string.Format("Request URL: {0}", context.Request.RequestUri.ToString()) : "";
        logMsg.Level = MesageLevel.Error;
        logMsg.MachineName = Environment.MachineName;
        logMsg.Message = context.Exception.Message;

        Logger.LogError(logMsg);
    }
}

Here is the how I am handling errors:

public class GlobalExceptionHandler : System.Web.Http.ExceptionHandling.ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        var metadata = new ErrorData
        {
            Message = "An error occurred! Please use the ticket ID to contact our support",
            DateTime = DateTime.Now,
            RequestUri = context.Request.RequestUri,
            ErrorId = //get the ID already logged
        };

        var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, metadata);
        context.Result = new ResponseMessageResult(response);        
    }
}

Since exception logging happens before handling, what is the best way to pass the ID from Exception Logger to Exception Handler to send the end user the corresponding error Id?

1 Answer 1

4

You could add it to HttpRequestMessage.Properties:

public static class HttpRequestMessageExtensions
{
    private const string LogId = "LOG_ID";

    public static void SetLogId(this HttpRequestMessage request, Guid id)
    {
        request.Properties[LogId] = id;
    }

    public static Guid GetLogId(this HttpRequestMessage request)
    {
        object value;
        if (request.Properties.TryGetValue(LogId, out value))
        {
            return (Guid) value;
        }

        return Guid.Empty;
    }
}

Then use these extension methods in your logger/handler:

public class GlobalExceptionLogger : System.Web.Http.ExceptionHandling.ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        LogMessage logMsg = new LogMessage();
        logMsg.ID = System.Guid.NewGuid().ToString();
        logMsg.MessageType = MessageType.ResourceServerAPI;
        logMsg.SenderMethod = context.Request.RequestUri != null ? string.Format("Request URL: {0}", context.Request.RequestUri.ToString()) : "";
        logMsg.Level = MesageLevel.Error;
        logMsg.MachineName = Environment.MachineName;
        logMsg.Message = context.Exception.Message;

        // Set the ID
        context.Request.SetLogId(logMsg.ID);

        Logger.LogError(logMsg);
    }
}

public class GlobalExceptionHandler : System.Web.Http.ExceptionHandling.ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        // Get the ID
        var id = context.Request.GetLogId();

        var metadata = new ErrorData
        {
            Message = "An error occurred! Please use the ticket ID to contact our support",
            DateTime = DateTime.Now,
            RequestUri = context.Request.RequestUri,
            ErrorId = id

        };

        var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, metadata);
        context.Result = new ResponseMessageResult(response);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.