using global exception handeling messes up Delegat

2019-05-31 15:02发布

When ovveride the IExceptionHandler, the response does not reach the DelegatingHandler when a unexpected exception occurs. How can I fix this?

In webapi 2, I want to implement a audit logger for request and response messages. I also want to add a global exception handler. However, when I replace the IExceptionHandler with my custom implementation. the response never reaches the DelegatingHandler -on exception - And thus the audit for response is lost.

in WebApiConfig

// add custom audittrail logger
config.MessageHandlers.Add(new AuditLogHandler());
// replace global exception handeling
config.Services.Replace(typeof(IExceptionHandler), new WebAPiExceptionHandler());

Custom Exception Handler

public class WebAPiExceptionHandler : ExceptionHandler
{
    //A basic DTO to return back to the caller with data about the error
    private class ErrorInformation
    {
        public string Message { get; set; }
        public DateTime ErrorDate { get; set; }
    }

    public override void Handle(ExceptionHandlerContext context)
    {
        context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,
        new ErrorInformation { Message = "Iets is misgegaan", ErrorDate = DateTime.UtcNow }));
    }
}

Custom Auditlogger

public class AuditLogHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Content != null)
        {
            var task = await request.Content.ReadAsStringAsync();

            // .. code for loggign request
        }

        var result = await base.SendAsync(request, cancellationToken);

        // .. code for logging response
        // when I do not replace WebAPiExceptionHandler, code is reachred here
        // When I Do use WebAPiExceptionHandler, code is not reached here

        return result;
    }
}

Code for throwing exception in webapi

public class Values_v2Controller : ApiController
{
    public string Get(int id)
    {
        throw new Exception("haha");
    }
}

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-05-31 15:36

The problem is that ExceptionHandler only executes Handle(ExceptionHandlerContext context) method if ShouldHandle(ExceptionHandlerContext context) returns true.

Overriding bool ShouldHandle(ExceptionHandlerContext context) to always return true fix the problem for me.

查看更多
聊天终结者
3楼-- · 2019-05-31 16:02

Dont use ExceptionHandler as base class, implement interface IExceptionHandler

public class WebAPiExceptionHandler : IExceptionHandler
{
    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
    {
        var fout = new ErrorInformation
        {
            Message = "Iets is misgegaan"
            , ErrorDate = DateTime.UtcNow
        };

        var httpResponse = context.Request.CreateResponse(HttpStatusCode.InternalServerError, fout);

        context.Result = new ResponseMessageResult(httpResponse);

        return Task.FromResult(0);
    }

    private class ErrorInformation
    {
        public string Message { get; set; }
        public DateTime ErrorDate { get; set; }
    }
}
查看更多
登录 后发表回答