如何使Project Reactor 3 flatMapMany中的异常触发自定义异常处理器?
问题:类型不存在时无法触发预期的404响应
需求说明
- 根据指定
typeId获取产品列表,若该类型不存在则返回404响应。
现有代码
端点代码
@Get("/products/{typeId}/products") @Operation(description = "Returns the products of the specified type.") @ApiResponse(responseCode = "200", description = "List of products.") @ApiResponse(responseCode = "404", description = "type Id does not exist.") @ApiResponse(responseCode = "500", description = "Internal Error.") public Flux<Asset> findProductsByTypeId(long typeId) { return typeService.findType(typeId) .flatMapMany( type -> { LOGGER.info("On success!"); return typeService.findProductsByTypeId(typeId); }, error -> { LOGGER.info("On error!"); Flux.error(() -> new TypeException(typeId)); }, null); }
异常处理器代码
@Singleton @Requires(classes = TypeException.class) public class TypeExceptionHandler implements ExceptionHandler<TypeException, HttpResponse<JsonError>> { @Override public HttpResponse<JsonError> handle(HttpRequest request, TypeException exception) { return HttpResponse.<JsonError>notFound(new JsonError(exception.getMessage()) .link(Link.SELF, Link.of(request.getUri()))); } }
问题现象
类型存在时可正常返回200及产品列表;但类型不存在时,抛出的TypeException未触发预期的404响应。尝试将Flux.error(() -> new TypeException(typeId))替换为throw new TypeException(typeId),问题仍未解决。
解决方案
1. 修复错误处理Lambda的返回值缺失问题
原代码中flatMapMany的错误处理Lambda仅创建了错误流,但未返回该流,导致异常信号无法被发送到下游。修改如下:
error -> { LOGGER.info("On error!"); return Flux.error(() -> new TypeException(typeId)); // 补充return语句 }
2. 处理类型不存在时返回空Mono的场景
如果typeService.findType(typeId)在类型不存在时返回的是Mono.empty()而非抛出异常,flatMapMany的错误映射器不会被触发,此时需要通过switchIfEmpty主动抛出异常:
public Flux<Asset> findProductsByTypeId(long typeId) { return typeService.findType(typeId) // 当findType返回空时,主动抛出TypeException .switchIfEmpty(Mono.error(() -> new TypeException(typeId))) .flatMapMany(type -> { LOGGER.info("On success!"); return typeService.findProductsByTypeId(typeId); }); }
3. 确认异常处理器生效条件
- 确保
TypeException是运行时异常(继承自RuntimeException),无需在端点方法上声明抛出。 - 验证
TypeExceptionHandler被框架正确扫描(比如Micronaut中@Singleton和@Requires注解配置无误)。
内容的提问来源于stack exchange,提问作者mohamed didi
相关产品推荐
相关产品推荐

