Изменение полей ошибки

274
12 ноября 2017, 14:49

Если при запросе что-то пошло не так, то RestController выкинет json такого вида:

{
    "timestamp": 1510417124782,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.netflix.hystrix.exception.HystrixRuntimeException",
    "message": "ApplicationRepository#save(Application) failed and no fallback available.",
    "path": "/application"
}

Объект какого класса был сериализован для этого ? Могу я как-то влиять на этот объект и заносить в рантайме статус и сообщение этого объекта ?

Answer 1

Покурил туториалы и доки и вот, что я понял:

По умолчанию тот json, что мы видим является объектом класса DefaultErrorAttributes.

Задать свой обработчик rest - ошибок не так уж и сложно. Для этого нужно знать о следующих вещах:

ResponseEntityExceptionHandler - класс, который собственно и занимается перехватом исключений и решает, что необходимо вернуть пользователю. У него много методов с названием по типу handle + название исключения.

ControllerAdvice - аннотация, которая дает "советы" группе контроллеров. По сути это некий хук для них. По умолчанию аннотация действует на все контролллеры, но в ее параметрах есть опции для указания конкретных групп.

ExceptionHandler - аннотация для ловли определенных ошибок.

Соответственно, для того, чтобы поймать некоторое исключение, обработать его и отдать что-то пользователю необходимо создать класс с аннотацией ControllerAdvice и унаследовать его от ResponseEntityExceptionHandler. После чего переопределить нужное исключение.

Примерно вот так:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
    @Override
    protected ResponseEntity<Object> handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {
        return super.handleAsyncRequestTimeoutException(ex, headers, status, webRequest);
    }
}

В случае, если мы хотим обработать свое исключение или какое-то другое специфическое исключение не из класса ResponseEntityExceptionHandler можно использовать конструкцию такого вида:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(HystrixRuntimeException.class)
    protected ResponseEntity<Object> handleHystrixRuntimeException(HystrixRuntimeException e) {
        HttpTypicalError error = getHttpTypicalError(e);
        return new ResponseEntity<>(new ErrorAnswer(error.getMessage()),
                HttpStatus.valueOf(error.getStatus()));
    }
}
READ ALSO
Голосовые сообщения в Android

Голосовые сообщения в Android

Как в андроид можно реализовать голосовые сообщенияЕсть ли какие-нибудь библиотеки или хотя бы просто алгоритм что нужно для создания и отправки...

251
Получение всех методов пакета

Получение всех методов пакета

Как узнать все методы пакета? С помощью Reflections понял, как получить методы класса, но как получить все методы пакета?

315
Запись трёх полей в массив

Запись трёх полей в массив

Пытаюсь записать в двухмерный массив 3 параметраКомпилятор пишет, что

225
SelectNodes в HtmlNodeCollection (HTMLAgilityPack)

SelectNodes в HtmlNodeCollection (HTMLAgilityPack)

Добрый день! Изучаю парсерыСтолкнулся с проблемой, что при:

216