You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:30:39