Axon框架聚合类中@ExceptionHandler未触发如何解决
问题原因
- 你在聚合类中定义的Axon
@ExceptionHandler是实例级别的异常处理器,仅能处理当前已经完成初始化的聚合实例的非构造函数@CommandHandler抛出的异常。你当前的异常是在聚合构造函数的CommandHandler中抛出的,此时聚合实例还未创建完成,实例方法的异常处理器自然无法被调用。 - 额外注意:Spring MVC提供的
@ExceptionHandler/@RestControllerAdvice仅能处理Web请求链路的异常,和Axon命令总线的处理链路完全隔离,也无法捕获命令执行阶段的异常。
解决方法
- 处理构造函数CommandHandler的异常:注册全局命令拦截器统一处理
在B应用中添加Axon命令拦截器配置,即可捕获所有命令执行阶段的异常,示例代码如下:
import org.axonframework.commandhandling.CommandHandlerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AxonExceptionConfig { @Bean public CommandHandlerInterceptor paymentExceptionInterceptor() { return (commandMessage, unitOfWork, interceptorChain) -> { try { return interceptorChain.proceed(); } catch (IllegalStateException e) { // 替换为你原来要在聚合异常处理器中执行的逻辑 System.out.println(e.getMessage()); // 处理完成后可选择是否继续抛出异常给调用端(即A应用的Saga) throw e; } }; } }
- 仅处理非构造函数CommandHandler的异常:无需额外改造
如果异常是在聚合普通成员方法的@CommandHandler中抛出,你当前的@ExceptionHandler写法本身是有效的,可直接触发。你可以用下面的测试代码验证:
// 先补充一个测试命令 public record UpdatePaymentStatusCommand(String paymentId, PaymentStatus status) {} // 在PaymentAggregate中添加普通CommandHandler @CommandHandler public void handle(UpdatePaymentStatusCommand cmd) { throw new IllegalStateException("普通CommandHandler抛出的测试异常"); }
发送该命令时,你聚合中定义的error异常处理方法会正常触发。
内容的提问来源于stack exchange,提问作者Yong D
相关产品推荐
相关产品推荐

