2013-01-18 2 views
1

우리의 응용 프로그램에서는 매우 간단한 로깅 훅 세트 (MVC 및 API 컨트롤러의 IExceptionFilters와 Application_Error()의 catch-all)가 있지만, 어떤 것도 트리거하지 않는 전체 카테고리의 오류가 있습니다. 예외가 WebAPI 자체 또는 내부적으로 사용되는 것으로부터 (예를 들어, 의존성 해결 자에 의해 생성되는 클래스의 형식 초기화 자 같이) 던져지면, 클라이언트에게 보내지는 500 응답 만받습니다.내부 웹 API 오류를 어떻게 처리해야합니까?

오류 세부 정보를 캡처하는 유일한 방법은 HttpConfiguration.IncludeErrorDetailPolicy를 사용하여 오류 세부 정보를 내보내는 응용 프로그램을 구성하는 것입니다. 그러나 오류 세부 정보를 전 세계에 전달하는 것은 나쁜 습관입니다. d를 완전히 해제하거나 조건부로 설정하는 것이 좋습니다 (예 : local-only.). 그러나 이것은 응용 프로그램이 실행중인 서버로 원격 작업을하고 응답을 검사 할 수있는 도구를 사용하여 API를 로컬로 호출하는 것을 의미합니다 (IE 또는 Chrome과 같은)를 사용하여 진행 상황을 파악할 수 있습니다.

비슷한 질문 (here)에서 또 다른 질문을 보았습니다. 응답을 조사하기 위해 DelegatingHandler를 사용하여 제시된 해결책이 우리의 요구를 충족시키지 못합니다. 실제로 연결할 수있는 이벤트가 없는지, 확장 점을 사용할 수 있습니까? 아니면 실제 예외가 발생했을 때이를 캡처 할 수 있습니까?

(제쳐두고, IncludeErrorDetailPolicy를 Always로 변경하고 다른 스레드에서 제공되는 솔루션을 사용하여 MessageHandler의 오류 세부 정보를 캡처하고 로그에 기록한 다음이를 수동으로 스크럽하여 클라이언트,하지만 그것은 심한 해킹 것입니다.)

생각? :/

+0

왜 MessageHandler 접근 방식이 효과가 없습니까? –

+0

필자는 그것을 오해하고 있을지 모르지만, 필자가 읽는 방법부터, 로그 할 수있는 예외 객체를 얻는 유일한 방법은 내 질문 끝에 언급 된 해킹을 따르는 것입니다. 모든 응답에서 오류 세부 정보를 포함 할 수있게하는 것입니다 그런 다음 해당 오류 세부 정보를 구문 분석하여 원래 throw 된 예외를 재구성하려고 시도한 다음 클라이언트에서 해당 세부 정보를 수동으로 스크럽하여 클라이언트에 보냅니다. .. 그리고 그게 효과가있는 동안, 그것은 조잡하고, 부서지기 쉽고, 진단 정보를 잃어 버리거나 의도하지 않게 그 정보를 고객에게 유출하는 경향이 있습니다. –

+0

진단 정보를 보존하고 클라이언트에 정보 유출을 방지 하시겠습니까? 어떤 종류의 답장을 보내시겠습니까? 왜 디폴트가 당신을 위해 일하지 않습니까? 디버깅을 위해 로컬 시스템에 대한 전체 진단 정보를 얻을 수 있으며 원격 클라이언트로 정보가 유출되지 않습니다. –

답변

0

좋아요, 당신이하려는 일을 이해합니다. 명확히 해 주셔서 감사합니다. WebAPI는 오류 응답이 반드시 예외에 의해 야기되는 것은 아니라는 모델을 가지고 있습니다. 누구나 예외를 던지지 않고 예를 들어 400으로 HttpResponseMessage를 반환 할 수 있습니다. 그리고 많은 경우, 내장 된 프레임 워크 오류는 예외를 발생시키지 않고 동일한 방식으로 작동합니다.

이제 내 생각에 당신이 제안한 소리가 나에게 잘 들린다 고 생각합니다. ErrorDetailPolicy를 Always로 설정하고 오류를 기록하고 메시지 만 포함하는 다른 HttpError를 사용하는 메시지 처리기를 구현할 수 있습니다. 다음과 같이 표시됩니다.

public class ErrorHandlingMessageHandler : DelegatingHandler 
{ 
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     HttpResponseMessage response = await base.SendAsync(request, cancellationToken); 
     HttpError error; 
     if (response.TryGetContentValue(out error)) 
     { 
      LogError(error) 
      // Use an HttpError that doesn't leak internal information 
      (response.Content as ObjectContent).Value = new HttpError(error.Message); 
     } 

     return response; 
    } 
} 

기존 오류를 제거하지 않습니다. 우리는 정보 누설의 위험을 줄이기 위해 새로운 제품을 만들고 있습니다. 메시지는 항상 되돌려 보내야 안전합니다. 모델 상태를 다시 전송하는 것은 아니지만 필요할 경우 항상 새 오류로 복사 할 수 있습니다.

이 문제에 대한 한 가지 생각은 로컬 클라이언트에 보낸 응답을 기록한 다음 원격 클라이언트에 오류 세부 정보가없는 안전한 메시지를 보낼 수 있다는 것입니다.

1

Microsoft 파트너 네트워크를 통해 지원 요청을 시작했으며 더 나은 대답을 얻었습니다.

아이디어는 플랫폼의 기본 IHttpControllerActivator 구현을 기본 컨트롤러 생성 동작을 원하는 추가 동작으로 래핑하는 것으로 대체하는 것입니다.

여기서는 DefaultHttpControllerActivator의 Create 메소드를 try/catch/throw 구문으로 래핑하고 로깅 서비스를 호출하는 것을 의미합니다. 그것은 100 % 적용 범위를 제공하지 않을 수도 있지만, 우리가 놓치고있는 대부분의 예외는 컨트롤러 생성을 다루므로 많은 도움이됩니다.

HttpControllerDispatcher 안에 HandleException 메서드를 연결하는 것이 정말 좋겠지 만 개인적이든 정적이든 상관 없습니다.

+0

+1 그리고 단지 주석 : 'IHttpControllerSelector','IHttpActionSelector' 및'IHttActionInvoker'를이 내부 오류에 대한 완전한 제어권으로 대체하십시오. – Konamiman

관련 문제