Перехват ArithmeticException в RestController в SpringBoot 2.0.4.RELEASE - PullRequest
0 голосов
/ 31 августа 2018

У меня есть базовое приложение SpringBoot 2.0.4.RELEASE. Использование Spring Initializer, JPA, встроенного Tomcat, механизма шаблонов Thymeleaf и пакета в качестве исполняемого файла JAR.

Я создал этот класс для управления Исключениями:

@ControllerAdvice
@RestControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    public RestResponseEntityExceptionHandler() {
        super();
    }


    // 500

    @ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
    /*500*/
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
        logger.error("500 Status Code", ex);

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

метод Обрабатывает исключения RuntimeException и ArithmeticException расширяет RuntimeException.

Чтобы проверить это, я создал этот метод;

GetMapping(path = "/getUsers", consumes = "application/json", produces = "application/json")
public ResponseEntity<List<User>> testErrors(HttpServletRequest request) {

    double ss = 3 /0;

    return ResponseEntity.ok(userService.findAll());

}

ожидает, что воля вернет только HttpStatus.INTERNAL_SERVER_ERROR, но вместо этого вернет "

{"timestamp":"2018-08-31T09:21:21.717+0000","status":500,"error":"Internal Server Error","message":"/ by zero","trace":"java.lang.ArithmeticException: / by zero\n\tat ...

С помощью этого метода

 @ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
    /*500*/
    public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
        logger.error("500 Status Code", ex);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
    }

У меня есть полный след: {"timestamp":"2018-09-03T07:04:58.803+0000","status":500,"error":"Internal Server Error","message":"/ by zero","trace":"java.lang.ArithmeticException: / by zero\n\tat

и с этим я не вижу ничего в консоли с curl:

 @ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
    /*500*/
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void handleInternal(final RuntimeException ex, final WebRequest request) {
        logger.error("500 Status Code", ex);

    }

и этот другой, тоже ничего в консоли:

@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
    /*500*/
    public ResponseEntity<Object> handleInternal(final RuntimeException ex, final WebRequest request) {
        logger.error("500 Status Code", ex);


        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

    }

Ответы [ 3 ]

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

Попробуйте это:

@ExceptionHandler({NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class})
/* 500 */
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handleInternal(final RuntimeException ex, final WebRequest request) {
    logger.error("500 Status Code", ex);

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

Возможно, piradian не указал на это конкретно, но, похоже, проблема в типе возврата вашего handleInternal метода. В коде, который вы предоставили, тип возврата - BodyBuilder, а вы возвращаете значение, возвращаемое ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR). На самом деле, как подсказывает имя BodyBuilder, оно представляет собой реализацию Pattern Builder . Что вы действительно должны сделать в этом случае, это:

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

И измените тип возвращаемого значения метода на ResponseEntity или ResponseEntity<Object> (тело в вашем случае пустое, поэтому большой разницы нет).

Однако, учитывая, что в вашем примере не возвращено тело, и у вас уже есть метод, помеченный @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR), все, что вы можете сделать, это изменить тип возвращаемого значения на void и ничего не возвращать - это точно что пирадиан предложил. Это должно сработать.

0 голосов
/ 31 августа 2018

используйте это

@RestControllerAdvice//insted of @ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {    
   @ExceptionHandler(value = { Exception.class, RuntimeException.class })
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
        logger.error("500 Status Code", ex);

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...