异常堆栈跟踪和原因未映射到 Micronaut 2.5.8 中的自定义全局异常处理

Exception stacktrace and cause not mapped to the custom global exception handling in 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 也有一个接受 Throwable 的单参数构造函数,因此 GlobalException(Throwable throwable) 有效地隐藏了 RuntimeException(Throwable throwable).

因此当您的控制器到达:

return Maybe.error(new GlobalException(error));
  1. error 正在被吞噬
  2. exception.getLocalizedMessage() returns null 因为 RuntimeException(Throwable throwable) 构造函数无法将 throwable 传播到 Exception(Throwable throwable)RuntimeException 扩展Exception) 并且 GlobalException 不会覆盖 Exception#getLocalizedMessage()
  3. LOG.error(exception.getCause().getCause().getMessage()) 正在投掷 a NullPointerException 因为 exception.getCause() 由于 error 被吞下而返回 null(来自列表项 1

总之,要么不要在GlobalException中隐藏RuntimeException(Throwable throwable),通过:

public class GlobalException extends RuntimeException {}

或者直接从 GlobalException(Throwable throwable) 调用 RuntimeException(Throwable throwable),通过:

public class GlobalException extends RuntimeException {
     public GlobalException(Throwable throwable) {
         super(throwable);
     }
}