Пользовательская обработка исключений в сервисе ServiceStack REST

У меня есть служба REST ServiceStack, и мне нужно реализовать настраиваемую обработку ошибок. Мне удалось настроить ошибки службы, установив AppHostBase.ServiceExceptionHandler на пользовательскую функцию.

Однако для других типов ошибок, таких как ошибки проверки, это не работает. Как я могу охватить все случаи?

Другими словами, я пытаюсь добиться двух вещей:

  1. Установите мои собственные коды состояния HTTP для каждого типа исключения, которое может появиться, включая ошибки, не связанные с обслуживанием (проверка)
  2. Возвращать мой собственный объект ошибки (не ResponseStatus по умолчанию) для каждого типа ошибки

Как мне добиться этого?


person Alex G.    schedule 24.03.2013    source источник


Ответы (2)


AppHostBase.ServiceExceptionHandler Глобальный обработчик обрабатывает только исключения службы. Для обработки исключений, возникающих вне служб, вы можете установить глобальный обработчик AppHostBase.ExceptionHandler, например:

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, вам потребуется доступ и использование правильный сериализатор для запроса от IAppHost.ContentTypeFilters.

Подробнее об этом можно узнать на странице вики по обработке ошибок.

person mythz    schedule 24.03.2013
comment
Я боялся, что это будет громоздко. Что, если я хочу просто изменить коды состояния HTTP для исключений, не связанных с обслуживанием? Могу ли я подключить где-нибудь функцию, которая оценивает каждое исключение и устанавливает свой код состояния HTTP? - person Alex G.; 25.03.2013
comment
У вас есть доступ к res HttpResponse, поэтому вы можете установить для него любые свойства ответа. Прочтите страницу ошибок, чтобы узнать, как сопоставить исключения с кодами состояния. - person mythz; 25.03.2013

Я улучшил ответ @mythz.

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.
    });
}
person Jim G.    schedule 04.09.2015
comment
Это отражает новейшие версии ServiceStack. - person Stephen Collins; 24.10.2016