program tip

ASP.NET 웹 API에서 처리되지 않은 모든 예외를 포착하십시오.

radiobox 2020. 7. 27. 07:48
반응형

ASP.NET 웹 API에서 처리되지 않은 모든 예외를 포착하십시오.


어떻게 잡을 않습니다 모든 내가 그들을 로그인 할 수 있도록 ASP.NET 웹 API의 발생 처리되지 않은 예외를?

지금까지 나는 시도했다 :

  • 작성 및 등록 ExceptionHandlingAttribute
  • Application_Error메소드 구현Global.asax.cs
  • 구독 AppDomain.CurrentDomain.UnhandledException
  • 구독 TaskScheduler.UnobservedTaskException

ExceptionHandlingAttribute성공적으로 예를 들어, 컨트롤러 액션 메소드와 액션 필터 내에서 발생하고 있지만 다른 예외가 처리되지 않는 예외를 처리 :

  • IQueryable액션 메소드에 의해 리턴 된 예외 가 실행되지 않을 때 발생하는 예외
  • 메시지 처리기에 의해 throw 예외 (예 HttpConfiguration.MessageHandlers)
  • 컨트롤러 인스턴스를 생성 할 때 예외 발생

기본적으로 예외로 인해 500 Internal Server Error가 클라이언트로 반환되면 예외를 기록하고 싶습니다. Application_ErrorWeb Forms 및 MVC에서이 작업을 잘 구현 했습니다. Web Api에서 무엇을 사용할 수 있습니까?


이제 WebAPI 2.1에서 가능합니다 ( 새로운 기능 참조 ).

하나 이상의 IExceptionLogger 구현을 작성하십시오. 예를 들면 다음과 같습니다.

public class TraceExceptionLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        Trace.TraceError(context.ExceptionContext.Exception.ToString());
    }
}

그런 다음 구성 콜백 내에서 애플리케이션의 HttpConfiguration에 등록하십시오.

config.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());

또는 직접 :

GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());

Yuval의 답변은 링크 된 페이지 에 명시된대로 로깅이 아닌 웹 API가 처리 한 처리되지 않은 예외에 대한 응답을 사용자 정의하는 것 입니다. 자세한 내용은 페이지의 사용시기 섹션을 참조하십시오. 로거는 항상 호출되지만 핸들러는 응답을 보낼 수있는 경우에만 호출됩니다. 간단히 말해서 로거사용하여 로그하고 핸들러를 사용하여 응답을 사용자 정의하십시오.

그건 그렇고, 나는 어셈블리 v5.2.3을 사용하고 있으며 ExceptionHandler클래스에는 HandleCore메소드 가 없습니다 . 그에 상응하는 것은 Handle입니다. 그러나 ExceptionHandler(유발의 답변에서와 같이 ) 단순히 서브 클래 싱 은 작동하지 않습니다. 필자의 경우 IExceptionHandler다음과 같이 구현 해야합니다.

internal class OopsExceptionHandler : IExceptionHandler
{
    private readonly IExceptionHandler _innerHandler;

    public OopsExceptionHandler (IExceptionHandler innerHandler)
    {
        if (innerHandler == null)
            throw new ArgumentNullException(nameof(innerHandler));

        _innerHandler = innerHandler;
    }

    public IExceptionHandler InnerHandler
    {
        get { return _innerHandler; }
    }

    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
    {
        Handle(context);

        return Task.FromResult<object>(null);
    }

    public void Handle(ExceptionHandlerContext context)
    {
        // Create your own custom result here...
        // In dev, you might want to null out the result
        // to display the YSOD.
        // context.Result = null;
        context.Result = new InternalServerErrorResult(context.Request);
    }
}

로거와 달리 기본 처리기를 추가하지 않고 교체하여 처리기를 등록합니다.

config.Services.Replace(typeof(IExceptionHandler),
    new OopsExceptionHandler(config.Services.GetExceptionHandler()));

내 자신의 질문에 대답하는 것은 불가능합니다!

Handling all exceptions that cause internal server errors seems like a basic capability Web API should have, so I have put in a request with Microsoft for a Global error handler for Web API:

https://aspnetwebstack.codeplex.com/workitem/1001

If you agree, go to that link and vote for it!

In the meantime, the excellent article ASP.NET Web API Exception Handling shows a few different ways to catch a few different categories of error. It's more complicated than it should be, and it doesn't catch all interal server errors, but it's the best approach available today.

Update: Global error handling is now implemented and available in the nightly builds! It will be released in ASP.NET MVC v5.1. Here's how it will work: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling


You can also create a global exception handler by implementing the IExceptionHandler interface (or inherit the ExceptionHandler base class). It will be the last to be called in the execution chain, after all registered IExceptionLogger:

The IExceptionHandler handles all unhandled exceptions from all controllers. This is the last in the list. If an exception occurs, the IExceptionLogger will be called first, then the controller ExceptionFilters and if still unhandled, the IExceptionHandler implementation.

public class OopsExceptionHandler : ExceptionHandler
{
    public override void HandleCore(ExceptionHandlerContext context)
    {
        context.Result = new TextPlainErrorResult
        {
            Request = context.ExceptionContext.Request,
            Content = "Oops! Sorry! Something went wrong."        
        };
    }

    private class TextPlainErrorResult : IHttpActionResult
    {
        public HttpRequestMessage Request { get; set; }

        public string Content { get; set; }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = 
                             new HttpResponseMessage(HttpStatusCode.InternalServerError);
            response.Content = new StringContent(Content);
            response.RequestMessage = Request;
            return Task.FromResult(response);
        }
    }
}

More on that here.


I thought my new global.asax.Application_Error method wasn't being consistently called for unhandled exceptions in our legacy code.

Then I found a few try-catch blocks in the middle of the call stack that called Response.Write on the Exception text. That was it. Dumped the text on the screen then killed the exception stone dead.

참고URL : https://stackoverflow.com/questions/16028919/catch-all-unhandled-exceptions-in-asp-net-web-api

반응형