используйте @ControllerAdvice и @ExceptionHandler, но по-прежнему допускайте сопоставление исключений по умолчанию - PullRequest
0 голосов
/ 02 июня 2019

Когда я использую @ControllerAdvice с аннотацией @ExceptionHandler, тогда нормальная обработка исключений больше не работает. Все результаты отображаются на HTML-странице с заголовком «HTTP Status 500 - Internal Server Error» и ничего не регистрируется в консоли.

Я создал простой @ControllerAdvice, как показано ниже, когда это не сработало, как ожидалось, я начал пробовать с basePackages и простирался от ResponseEntityExceptionHandler.

@ControllerAdvice(basePackages = "nl.xxxx.events")
public class EventExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(EventExceptionHandler.class);

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(EventNotFoundException.class)
    public void handlePersonNotFound(RuntimeException ex) {
        logger.error("error", ex);
    }
}

В сервисе я выкидываю исключение, используя:

public Event findById(Long id) {
    return this.eventRepository.findById(id).orElseThrow(() -> new EventNotFoundException(id));
}

Я пытался сравнить поток кода с * 1014 и без него, но есть множество разных вещей. Например, без @ControllerAdvice атрибут value HttpEntityMethodProcessor устанавливается с объектом, описывающим исключение. Но с @ControllerAdvice этот атрибут всегда null.

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

В качестве примера я хотел бы использовать ошибку «не удалось инициализировать прокси - нет сеанса», потому что это легко воспроизвести.

До того, как я добавил, пружина @ControllerAdvice дала следующий результат json:

{"timestamp":"2019-06-02T19:17:14.223+0000","status":500,"error":"Internal Server Error","message":"Could not write JSON: failed to lazily initialize a collection of role: (truncated)....","path":"/events/find"}

и с журналом отладки:

2019-06-02 21:18:29.723 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.724 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:18:29.729  WARN 1588 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed 500 INTERNAL_SERVER_ERROR
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.730 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Sun Jun 02 21:18:29 CEST 2019, status=500, error=Internal Server Error, message=Could not (truncated)...]
2019-06-02 21:18:29.732 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 500

Но теперь возвращается:

<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1></body></html>

И с журналом отладки:

2019-06-02 21:20:33.682 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:20:33.688 DEBUG 22308 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:20:33.760  INFO 22308 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
2019-06-02 21:20:33.900 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:20:33.901 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:20:33.923 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception
2019-06-02 21:20:33.925 DEBUG 22308 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : No match for [application/json, text/plain, */*], supported: []
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 500 INTERNAL_SERVER_ERROR

Итак, в какой-то момент он просто говорит No match for [application/json, text/plain, */*], supported: [] и больше не возвращает красивое исключение JSON.

Есть идеи, что я делаю не так? изначально просто хочу, чтобы EventNotFoundException приводил к 404 вместо 500. Вероятно, в будущем я хотел бы также добавить контент.

1 Ответ

0 голосов
/ 04 июня 2019

Проблема в том, что вы пытаетесь обработать RuntimeException, который является слишком общим. public void handlePersonNotFound(RuntimeException ex) Вам также не нужно расширяться от ResponseEntityExceptionHandler.

Если вы напишите ExceptionHandler, который должен обрабатывать определенное исключение, метод handleException должен принять это конкретное исключение в качестве параметра. Также вам, вероятно, понадобится какой-нибудь ответ.

@ControllerAdvice
public class EventExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(getClass());

    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(EventNotFoundException.class)
    public String handlePersonNotFound(EventNotFoundException ex) {
        logger.error("error", ex);
        return ex.getMessage();
    }
}

Это даст основное тело ответа с сообщением об исключении и кодом ошибки.

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