I have a ServiceStack REST service and I need to implement custom error handling. I've been able to customize service errors by setting AppHostBase.ServiceExceptionHandler to a custom function.
However, for other types of errors, such as validation errors, this doesn't work. How can I cover all cases?
In other words, I'm trying to achieve two things:
How would I go about achieving this?
The AppHostBase.ServiceExceptionHandler
global handler only handles service exceptions.
To handle exceptions occurring outside of services you can set the global AppHostBase.ExceptionHandler
handler, 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);
};
}
To create and serialize a DTO to the response stream in the non-service ExceptionHandler
you would need to access and use the correct serializer for the request from IAppHost.ContentTypeFilters.
More details about is in the Error Handling wiki page.
I made improvements to @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.
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With