Spring boot Исключительная обработка - Неожиданный статус HTTP - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь реализовать некоторые пользовательские обработчики исключений в моем приложении для весенней загрузки, которые смогут обрабатывать пользовательские исключения и отображать соответствующее сообщение и код состояния.

Моя проблема: получение http status = 500, хотя тело ответа соответствует моему пользовательскому обработчику.

Код:

@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler({ BadRequestValidationFailureException.class, Exception.class })
public ResponseEntity<Object> handleAll(Exception ex, WebRequest request) {

    ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getMessage());

    return new ResponseEntity<Object>( apiError, new HttpHeaders(), HttpStatus.BAD_REQUEST );

}

И выдает исключение как:

throw new BadRequestValidationFailureException( "ERROR_CODE", "THIS IS THE MESSAGE" );

Вывод:

{
"timestamp": "2018-09-20T17:44:01.502Z",
"status": 500,
"error": "Internal Server Error",
"exception": "com.hotstar.payment.exception.BadRequestValidationFailureException",
"message": "[ ERROR_CODE ] THIS IS THE MESSAGE",
"path": "/my/api/path"
}

Странно то, чтоhttp ответ статус 500.

Пожалуйста, помогите.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Я получил хороший опыт работы со следующим шаблоном:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Map<MyProjectErrorCode, HttpStatus> CODE_STATUS_MAP = new EnumMap<>(MyProjectErrorCode.class);

    static {
        CODE_STATUS_MAP.put(MyProjectErrorCode.MYPROJ_ILLEGAL_PROPERTY, HttpStatus.BAD_REQUEST);
        CODE_STATUS_MAP.put(MyProjectErrorCode.MYPROJ_FOO, HttpStatus.BAD_REQUEST);
        CODE_STATUS_MAP.put(MyProjectErrorCode.MYPROJ_THIRDPARTYX_CLIENT, HttpStatus.INTERNAL_SERVER_ERROR);
        CODE_STATUS_MAP.put(MyProjectErrorCode.MYPROJ_UNKNOWN, HttpStatus.INTERNAL_SERVER_ERROR);
        CODE_STATUS_MAP.put(MyProjectErrorCode.THIRDPARTYX_BAR, HttpStatus.BAD_REQUEST);
        CODE_STATUS_MAP.put(MyProjectErrorCode.THIRDPARTYX_UNKNOWN, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(MyProjectException.class)
    public ResponseEntity<ErrorResponse> handleMyProjectException(MyProjectException ex) {
        ErrorResponse errorResponse = createErrorResponse(ex.getErrorCode(), ex.getMessage());
        HttpStatus httpStatus = determineHttpStatus(ex.getErrorCode());
        return handleErrorResponse(errorResponse, httpStatus);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {
        MyProjectErrorCode errorCode = MyProjectErrorCode.MYPROJ_ILLEGAL_PROPERTY;
        ErrorResponse errorResponse = createErrorResponse(errorCode, ex.getMessage());
        HttpStatus httpStatus = determineHttpStatus(errorCode);
        return handleErrorResponse(errorResponse, httpStatus);
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex) {
        MyProjectErrorCode errorCode = MyProjectErrorCode.MYPROJ_UNKNOWN;
        ErrorResponse errorResponse = createErrorResponse(errorCode, ex.getMessage());
        HttpStatus httpStatus = determineHttpStatus(errorCode);
        return handleErrorResponse(errorResponse, httpStatus);
    }

    private ResponseEntity<ErrorResponse> handleErrorResponse(ErrorResponse errorResponse, HttpStatus httpStatus) {
        return new ResponseEntity<>(errorResponse, httpStatus);
    }

    private ErrorResponse createErrorResponse(MyProjectErrorCode errorCode, String message) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setErrorCode(errorCode.name());
        errorResponse.setErrorMessage(message);
        return errorResponse;
    }

    private HttpStatus determineHttpStatus(MyProjectErrorCode errorCode) {
        return CODE_STATUS_MAP.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR);
}

Клиент может получить HttpStatus из ответа Http - нет необходимости добавлять его в тело JSON.

Специфичное для проекта перечисление MyProjectErrorCode позволяет сообщить клиентам подробный код ошибки.Клиент может проанализировать этот код ошибки и предпринять соответствующее действие или отобразить локализованное (определенное или общее) сообщение об ошибке на основе кода ошибки.

MyProjectErrorCode также позволяет вам сообщить, была ли ошибка создана в вашем коде (начиная с MYPROJ_) или если ошибка пересылается из сторонней службы 'x' (начиная с THIRDPARTYX _).

Вы также можете создавать подклассы MyProjectException и ErrorResponse для передачи более конкретных данных для конкретных случаев - просто добавьтедополнительный метод обработчика исключения для этого исключения.

0 голосов
/ 20 сентября 2018

Получил решение.Пришлось установить еще одну аннотацию:

@ResponseStatus(value = HttpStatus.BAD_REQUEST, code = HttpStatus.BAD_REQUEST, reason = "some reason")

Добавить это к handleAll методу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...