2013-03-24 73 views
6

我有一個ServiceStack REST服務,我需要實現自定義錯誤處理。我已經能夠通過將AppHostBase.ServiceExceptionHandler設置爲自定義函數來自定義服務錯誤。ServiceStack REST服務中的自定義異常處理

但是,對於其他類型的錯誤,例如驗證錯誤,這不起作用。我如何涵蓋所有情況?

換句話說,我試圖達到兩個目的:

  1. 設置自己的HTTP狀態代碼爲每一種例外的可能彈出,包括非服務錯誤(驗證)
  2. 爲每個錯誤類型返回我自己的自定義錯誤對象(不是默認的ResponseStatus)

我該如何去實現這個目標?

回答

11

AppHostBase.ServiceExceptionHandler全局處理程序僅處理服務異常。 爲了處理髮生的服務之外,你可以設置全局AppHostBase.ExceptionHandler處理器,e.g例外:

public override void Configure(Container container) 
{ 
    //Handle Exceptions occurring in Services: 
    this.ServiceExceptionHandler = (request, exception) => { 

     //log your exceptions here 
     ... 

     //call default exception handler or prepare your own custom response 
     return DtoUtils.HandleException(this, request, exception); 
    }; 

    //Handle Unhandled Exceptions occurring outside of Services, 
    //E.g. in Request binding or filters: 
    this.ExceptionHandler = (req, res, operationName, ex) => { 
     res.Write("Error: {0}: {1}".Fmt(ex.GetType().Name, ex.Message)); 
     res.EndServiceStackRequest(skipHeaders: true); 
    }; 
} 

創建和序列化DTO在非服務的響應流ExceptionHandler你需要access and use the correct serializer for the request from IAppHost.ContentTypeFilters

更多細節在Error Handling wiki page

+0

我擔心這會很麻煩。如果我只想修改非服務異常的HTTP狀態代碼,該怎麼辦?我可以在某處評估每個異常並設置它的HTTP狀態代碼嗎? – 2013-03-24 22:55:37

+0

您可以訪問'res' HttpResponse,以便您可以設置您想要的任何響應屬性。閱讀錯誤頁面瞭解如何將異常映射到狀態代碼。 – mythz 2013-03-24 23:09:34

+0

好的,我明白了。再次感謝您的幫助! – 2013-03-24 23:45:56

4

我對@mythz' answer做了改進。

public override void Configure(Container container) { 
    //Handle Exceptions occurring in Services: 

    this.ServiceExceptionHandlers.Add((httpReq, request, exception) = > { 
     //log your exceptions here 
     ... 
     //call default exception handler or prepare your own custom response 
     return DtoUtils.CreateErrorResponse(request, exception); 
    }); 

    //Handle Unhandled Exceptions occurring outside of Services 
    //E.g. Exceptions during Request binding or in filters: 
    this.UncaughtExceptionHandlers.Add((req, res, operationName, ex) = > { 
     res.Write("Error: {0}: {1}".Fmt(ex.GetType().Name, ex.Message)); 

#if !DEBUG 
     var message = "An unexpected error occurred."; // Because we don't want to expose our internal information to the outside world. 
#else 
     var message = ex.Message; 
#endif 

     res.WriteErrorToResponse(req, req.ContentType, operationName, message, ex, ex.ToStatusCode()); // Because we don't want to return a 200 status code on an unhandled exception. 
    }); 
} 
+0

這反映了最新版本的ServiceStack。 – 2016-10-24 14:40:59