提问人:Hadi Rifaii 提问时间:10/19/2023 更新时间:10/19/2023 访问量:46
标题:将异常从 Axon Saga 传播到 Spring Boot REST 控制器
Title: Propagating Exceptions from Axon Saga to Spring Boot REST Controller
问:
我正在做一个利用 Axon 框架和 Spring Boot 来实现 CQRS 和事件溯源模式的项目。在这个项目中,我定义了一个 Saga 来处理特定的业务流程。在此 Saga 中,当不满足某些条件时,我会抛出自定义 InvalidOrderException。这是我的传奇的简化版本:
@Slf4j
@NoArgsConstructor
public class OrderSaga {
// ...
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
@EventHandler
public void handle(OrderCreatedEvent orderCreatedEvent) {
// ...
try {
commandGateway.sendAndWait(reserveProductCommand);
} catch (CommandExecutionException ex) {
rollbackReservations();
throw new InvalidOrderException("The product ID: " + productId + " provided in the order is invalid ");
}
// ...
}
// ...
}
我想在我的 REST 控制器中处理此 InvalidOrderException,从该控制器发送启动此 Saga 的命令,以通知用户出现问题。这是我的 REST 控制器的相关部分:
public class OrderController {
// ...
@PostMapping
public ResponseEntity<ReadOrderDto> createOrder(@RequestBody CreateOrderDto createOrderDto){
CreateOrderCommand createOrderCommand = new CreateOrderCommand(
// ...
);
commandGateway.sendAndWait(createOrderCommand);
return new ResponseEntity<>(
createOrderCommand.toToReadProductDto(), HttpStatus.OK
);
}
// ...
}
为了处理 InvalidOrderException,我尝试创建一个用 @RestControllerAdvice 注释的 GlobalExceptionHandler 类,如下所示:
public class GlobalExceptionHandler {
@ExceptionHandler(InvalidOrderException.class)
public ResponseEntity<String> handleProductServiceException(InvalidOrderException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
}
}
但是,此 GlobalExceptionHandler 不会捕获从 Saga 引发的异常。我正在寻找一种方法将此异常传播回 REST 控制器,以向客户端发送有意义的错误响应。
我还使用了 Axon 的@ExceptionHandler注解,但这仅在在同一类中抛出异常时才有效,所以这没有帮助。
是否有推荐的方法来处理Spring Boot REST控制器中Axon Saga抛出的此类异常,特别是捕获和响应最初发送命令的这些异常?
谢谢。
答:
我不确定将某些东西从 Saga 返回给其余控制器是否是正确的方法。由于 Saga 用于可能很长的异步运行进程,因此从最初的 rest 调用开始,我只期望失败或 Ok,订单开始返回。
在Saga中,您可以发送相应的命令或事件,以便可以创建可以从中检索状态的投影。因此,例如,您可以对订单启动订阅查询,以在 UI 中提供反馈。
评论