1

试图在 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())抛出空指针异常

4

1 回答 1

2

GlobalException的构造函数有一个Throwable参数,它正在吞噬它(不做任何事情)。RuntimeException还有一个带 a 的单参数构造函数Throwable,因此GlobalException(Throwable throwable)有效地隐藏了RuntimeException(Throwable throwable)

因此,当您的控制器到达:

return Maybe.error(new GlobalException(error));
  1. error正在被吞噬
  2. exception.getLocalizedMessage()返回null,因为RuntimeException(Throwable throwable)构造函数不能传播throwableException(Throwable throwable)( RuntimeExceptionextends Exception) 并且GlobalException不会覆盖Exception#getLocalizedMessage()
  3. LOG.error(exception.getCause().getCause().getMessage())正在抛出一个NullPointerException因为被吞下而返回(来自列表exception.getCause()项)nullerror1

总之,要么不要隐藏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);
     }
}
于 2021-07-13T18:35:29.783 回答