#java #micronaut #micronaut-client #micronaut-rest
Вопрос:
Пытаюсь обработать глобальную обработку исключений в Micronaut, но трассировка стека исключений и причина не передаются обработчику исключений.
public class GlobalException extends RuntimeException{
public GlobalException(Throwable throwable){}
}
@Produces
@Singleton
@Requires(classes = {GlobalException.class, ExceptionHandler.class})
public class GlobalExceptionHandler implements ExceptionHandler<GlobalException, HttpResponse> {
private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@Override
public HttpResponse handle(HttpRequest request, GlobalException exception) {
LOG.error(exception.getLocalizedMessage());
LOG.error(exception.getCause().getCause().getMessage());
Arrays.stream(exception.getStackTrace()).forEach(item -> LOG.error(item.toString()));
return HttpResponse.serverError(exception.getLocalizedMessage());
}
}
Контроллер
public Maybe<FindProductCommand> get(ProductSearchCriteriaCommand searchCriteria) {
LOG.info("Controller --> Finding all the products");
return iProductManager.find(searchCriteria)
.onErrorResumeNext(error -> { return Maybe.error(new GlobalException(error));});
}
Фактическая ошибка не отображается в GlobalExceptionHandler. exception.getLocalizedMessage()
является нулевым и LOG.error(exception.getCause().getCause().getMessage())
создает исключение нулевого указателя
Ответ №1:
GlobalException
у конструктора есть Throwable
параметр, и он проглатывает его (ничего с ним не делая). RuntimeException
также имеет конструктор с одним аргументом , который принимает a Throwable
, поэтому GlobalException(Throwable throwable)
эффективно скрывается RuntimeException(Throwable throwable)
.
Таким образом, когда ваш контроллер доберется до:
return Maybe.error(new GlobalException(error));
error
проглатываетсяexception.getLocalizedMessage()
возвращаетnull
, такRuntimeException(Throwable throwable)
как конструктор не может перейтиthrowable
кException(Throwable throwable)
(RuntimeException
расширяетсяException
) иGlobalException
не переопределяетException#getLocalizedMessage()
LOG.error(exception.getCause().getCause().getMessage())
бросает,NullPointerException
потомуexception.getCause()
что возвращаетсяnull
изerror
-за того, что его проглотили (из элемента списка1
)
В заключение, либо не прячьтесь RuntimeException(Throwable throwable)
в GlobalException
, через:
public class GlobalException extends RuntimeException {}
Или просто вызовите RuntimeException(Throwable throwable)
из GlobalException(Throwable throwable)
, через:
public class GlobalException extends RuntimeException {
public GlobalException(Throwable throwable) {
super(throwable);
}
}