java - 异常堆栈跟踪和原因未映射到 Micronaut 2.5.8 中的自定义全局异常处理
问题描述
试图在 Micronaut 中处理全局异常处理,但是异常堆栈跟踪和原因没有被抛出到 ExceptionHandler。
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())
抛出空指针异常
解决方案
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
extendsException
) 并且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)
from GlobalException(Throwable throwable)
,通过:
public class GlobalException extends RuntimeException {
public GlobalException(Throwable throwable) {
super(throwable);
}
}
推荐阅读
- sql - 在 Join 中使用 Rank 函数
- python - Selenium 和 Python 到可执行文件
- php - PHP - 如何让应用程序读取美化的语言环境 uri 参数?
- bash - 检查为 git commit 暂存的任何文件是否与白名单不匹配
- java - 休眠验证器注释不适用于spring mvc
- angularjs - 为什么Angular / JS中的双花括号被称为插值?
- javascript - 使用 ReactJS 和 Firebase 进行身份验证
- javafx - 在 intelliJ 中将自定义组件添加到 FXML 场景构建器
- python - 熊猫使用相同的标准多次提取文本
- c++ - 目标文件在 Linux 上比在 macOS 或 Windows 上大 2.5 倍