【问题标题】:Catching Message Handling Exceptions with the @Exceptionhandler使用@Exceptionhandler 捕获消息处理异常
【发布时间】:2021-08-23 05:15:24
【问题描述】:

我有两个应用程序,例如)A、B

A 有一个 Saga B 只是网络应用程序

A 向 B 发送命令消息,然后 B 将该命令的异常发送给 A 的 Saga 并且 A 的 Saga 接收良好

和 B 有一个 @ExceptionHandler 我希望被调用但它不起作用

如何让它们被调用?


编辑

这是 A 应用程序的 Saga,它向 B 应用程序发送命令消息 并处理 B 发送的异常

@Saga
public class OrderSaga {

    @Autowired
    private transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "orderId")
    public void handle(CreateOrderEvent evt) {

        String paymentId = UUID.randomUUID().toString();

        SagaLifecycle.associateWith("paymentId", paymentId);
        commandGateway.send(new CreatedPaymentCommand(paymentId, evt.getUserId(),evt.getFoodPrice())).exceptionally(exp -> {
            System.out.println("got it");
            System.out.println(exp.getMessage());
            return null;
        });
    }

}

这是为测试抛出异常的 B 应用程序

@Aggregate
@NoArgsConstructor
public class PaymentAggregate {

    @AggregateIdentifier
    private String paymentId;
    private String userId;

    private PaymentStatus status;

    @CommandHandler
    public PaymentAggregate(CreatedPaymentCommand cmd) {

        throw new IllegalStateException("this exception was came from payment aggregates");
        // AggregateLifecycle.apply(new CreatedPaymentEvent(cmd.getPaymentId(),
        // cmd.getUserId(),cmd.getMoney()));
    }

    @ExceptionHandler(resultType = IllegalStateException.class)
    public void error(IllegalStateException exp) {
        System.out.println(exp.getMessage());
    }
    // I want this @ExceptionHandler to be invoked


    @EventSourcingHandler
    public void on(CreatedPaymentEvent evt) {
        this.paymentId = evt.getPaymentId();
        this.userId = evt.getUserId();
    }

}

如下所示的应用程序捕获异常

2021-08-24 11:46:43.534  WARN 14244 --- [ault-executor-2] o.a.c.gateway.DefaultCommandGateway      : Command 'com.common.cmd.CreatedPaymentCommand' resulted in org.axonframework.commandhandling.CommandExecutionException(this exception was came from payment aggregates)
got it
this exception was came from payment aggregates

但是B不是我认为B的@ExceptionHandler会捕捉到那个异常

简而言之,我怎样才能让 B 的 @ExceptionHandler 被调用

【问题讨论】:

  • 您能否分享一些您的 Saga 事件处理程序、异常处理程序和命令处理程序注释方法的 sn-ps?这将更好地了解您的应用程序中可能出现的问题。另外,您是否介意提供您正在使用的版本,以及是否为消息/事件存储设置了 Axon Server?
  • 感谢我编辑,我正在使用服务器的默认设置
  • 服务器版本为4.5.4.1

标签: axon


【解决方案1】:

它现在不起作用,因为异常是从聚合的构造函数中抛出的。 当您使用构造函数命令处理程序时,还没有实例存在。 如果没有实例,Axon Framework 无法识别您设置的 @ExceptionHandler 注释方法。

这是现阶段异常处理程序的唯一缺失点。老实说,参考指南应该对此更具体一些。不过,我相信这在未来会有所改变。

有一种不同的方法可以让命令处理程序构造聚合,该聚合可以使用@ExceptionHandler: 和@CreationPolicy 注释。顺便说一句,参考指南有this 来说明它。

因此,您可以使用AggregateCreationPolicy.ALWAYS 设置常规命令处理程序,而不是使用构造函数命令处理程序。 这会像这样调整您的样本:

@Aggregate
@NoArgsConstructor
public class PaymentAggregate {

    @AggregateIdentifier
    private String paymentId;
    private String userId;

    private PaymentStatus status;

    @CommandHandler
    @CreationPolicy(AggregateCreationPolicy.ALWAYS)
    public void handle(CreatedPaymentCommand cmd) {
        throw new IllegalStateException("this exception was came from payment aggregates");
        // AggregateLifecycle.apply(new CreatedPaymentEvent(cmd.getPaymentId(),
        // cmd.getUserId(),cmd.getMoney()));
    }

    @ExceptionHandler(resultType = IllegalStateException.class)
    public void error(IllegalStateException exp) {
        System.out.println(exp.getMessage());
    }
    // I want this @ExceptionHandler to be invoked


    @EventSourcingHandler
    public void on(CreatedPaymentEvent evt) {
        this.paymentId = evt.getPaymentId();
        this.userId = evt.getUserId();
    }

}

请在您的应用程序中尝试一下,@YongD。

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2011-05-12
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多