Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

c# - WebApi v2 ExceptionHandler not called

How comes that a custom ExceptionHandler is never called and instead a standard response (not the one I want) is returned?

Registered like this

config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());

and implemented like this

public class GlobalExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        context.Result = new ExceptionResponse
        {
            statusCode = context.Exception is SecurityException ? HttpStatusCode.Unauthorized : HttpStatusCode.InternalServerError,
            message = "An internal exception occurred. We'll take care of it.",
            request = context.Request
        };
    }
}

public class ExceptionResponse : IHttpActionResult
{
    public HttpStatusCode statusCode { get; set; }
    public string message { get; set; }
    public HttpRequestMessage request { get; set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(statusCode);
        response.RequestMessage = request;
        response.Content = new StringContent(message);
        return Task.FromResult(response);
    }
}

and thrown like this (test)

throw new NullReferenceException("testerror");

in a controller or in a repository.

UPDATE

I do not have another ExceptionFilter.

I found a trigger for this behavior:

Given URL

GET http://localhost:XXXXX/template/lock/someId

sending this header, my ExceptionHandler works

Host: localhost:XXXXX

sending this header, it doesn't work and the built-in handler returns the error instead

Host: localhost:XXXXX
Origin: http://localhost:YYYY

This might be an issue with CORS requests (I use the WebAPI CORS package globally with wildcards) or eventually my ELMAH logger. It also happens when hosted on Azure (Websites), though the built-in error handler is different.

Any idea how to fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Turns out the default only handles outermost exceptions, not exceptions in repository classes. So below has to be overridden as well:

public virtual bool ShouldHandle(ExceptionHandlerContext context)
{
    return context.ExceptionContext.IsOutermostCatchBlock;
}

UPDATE 1

WebAPI v2 does not use IsOutermostCatchBlock anymore. Anyway nothing changes in my implementation, since the new code in ShouldHandle still prevents my Error Handler. So I'm using this and my Error Handler gets called once. I catch errors in Controllers and Repositories this way.

public virtual bool ShouldHandle(ExceptionHandlerContext context)
{
    return true;
}

UPDATE 2

Since this question got so much attention, please be aware that the current solution is the one linked by @JustAMartin in the comments below.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...