micronaut Java 中的全局异常处理

问题描述

寻找更好的解决方案来处理 micronaut https://docs.micronaut.io/latest/guide/index.html#errorHandling 中的全局异常

控制器

DECLARE @CountFID int 
SET @CountFID = (SELECT COUNT(FID) FROM DataFoodView)

INSERT INTO FoodSara_tbl
SELECT FID + (@CountFID),Fname,Ftype,Fcount,FoodDate,Fregion,Fdescription
FROM dbo.DataFoodView
ORDER BY FoodDate

INSERT INTO FoodSara_tbl
SELECT FID + 2*(@CountFID),Fdescription
FROM dbo.DataFoodView
ORDER BY FoodDate

@Controller("/category") public class CategoryController { @Delete(uri = "/{id}") public Maybe<HttpResponse> delete(@NotBlank String id) { LOG.info(String.format("API --> Deleting the specified category")); return iCategoryManager.Count(id).flatMap(item -> { if (item > 0) { iCategoryManager.Delete(id).subscribe(); return Maybe.just(HttpResponse.noContent()); } else return Maybe.just(HttpResponse.notFound()); }); } } 导致如下异常,如何在 GlobalExceptionHandler

上捕获异常
iCategoryManager.Count(id)

全局异常处理

io.micronaut.core.serialize.exceptions.SerializationException: Incorrect message body size to deserialize to a Long
    at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes$LongSerDes.deserialize(JavaLangRabbitMessageSerDes.java:314)
    at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes$LongSerDes.deserialize(JavaLangRabbitMessageSerDes.java:306)
    at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes.deserialize(JavaLangRabbitMessageSerDes.java:81)
    at io.micronaut.rabbitmq.intercept.RabbitMQIntroductionAdvice.deserialize(RabbitMQIntroductionAdvice.java:323)
    at io.micronaut.rabbitmq.intercept.RabbitMQIntroductionAdvice.lambda$intercept$22(RabbitMQIntroductionAdvice.java:268)
    at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:132)
    at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onNext(RxInstrumentedSubscriber.java:59)
    at io.reactivex.internal.operators.flowable.FlowableTimeoutTimed$TimeoutSubscriber.onNext(FlowableTimeoutTimed.java:101)
    at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onNext(RxInstrumentedSubscriber.java:59)
    at io.reactivex.internal.subscriptions.DeferredScalarSubscription.complete(DeferredScalarSubscription.java:132)
    at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onSuccess(SingleToFlowable.java:62)
    at io.micronaut.reactive.rxjava2.RxInstrumentedSingleObserver.onSuccess(RxInstrumentedSingleObserver.java:65)
    at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback$FlatMapSingleObserver.onSuccess(SingleFlatMap.java:111)
    at io.micronaut.reactive.rxjava2.RxInstrumentedSingleObserver.onSuccess(RxInstrumentedSingleObserver.java:65)
    at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onSuccess(SingleDoFinally.java:73)
    at io.micronaut.reactive.rxjava2.RxInstrumentedSingleObserver.onSuccess(RxInstrumentedSingleObserver.java:65)
    at io.reactivex.internal.operators.single.SingleCreate$Emitter.onSuccess(SingleCreate.java:67)
    at io.micronaut.rabbitmq.reactive.RxJavaReactivePublisher$3.handleDelivery(RxJavaReactivePublisher.java:324)
    at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
    at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)

如何在控制器中hook GlobalExceptionHandler,因为它是一个响应式HTTP调用,所以异常是从netty服务器抛出的?

应用程序上发生的任何异常都应在 GlobalExceptionHandler

中捕获

解决方法

当服务器上发生异常时,会在 bean 上下文中查找与抛出的异常最匹配的 ExceptionHandler(通过处理程序的类型参数)。要处理所有异常,需要替换所有提供的异常处理程序。大约有十几个。

一种选择是替换默认的错误响应处理器。例如,这就是导致身体成为 HATEOS 的原因。有关详细信息,请参阅有关错误处理的 documentation

,

这个解决方案对我有用

@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().getMessage());
        Arrays.stream(exception.getStackTrace()).forEach(item ->  LOG.error(item.toString()));
        return HttpResponse.serverError(exception.getLocalizedMessage());
    }
}

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

控制器

  public Maybe<FindProductCommand> get(ProductSearchCriteriaCommand searchCriteria) {
        LOG.info("Controller --> Finding all the products");
        return iProductManager.find(searchCriteria)
                .onErrorResumeNext(throwable ->  { return Maybe.error(new GlobalException(throwable));});
    }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...