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

Reactor机制下GatewayFilter两段代码的差异及修正问询

GatewayFilter中Reactor错误处理的差异与修正

问题1:两段代码的差异及错误捕获范围确认

你的理解完全正确:

  • 版本A:onErrorResume操作符位于flatMap之后,因此会捕获**sample()执行阶段和chain.filter(...)后续链路执行阶段**产生的所有错误。
  • 版本B:onErrorResume位于flatMap之前,仅会捕获sample()执行时的错误,但由于onErrorResume返回的Mono<Void>与上游sample()返回的Mono<String>类型不匹配,导致编译失败。

问题2:版本B的修正方案(仅捕获sample()错误)

要实现仅处理sample()的错误,同时保证类型匹配,需让onErrorResume返回Mono<String>类型的流。可以在错误处理逻辑中先完成错误响应的写入,再返回空的Mono<String>(错误发生后无需传递字符串数据给后续flatMap),既满足类型要求,又能终止后续链路执行。

修正后的代码

// 修正后的Version B
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
    return sample()
        .onErrorResume(SampleException::class.java) { ex ->
            // 先写入错误响应,再转换为匹配类型的空流
            exchange.mutateToError()
                .then(Mono.empty<String>())
        }
        .onErrorResume {
            exchange.mutateToError()
                .then(Mono.empty<String>())
        }
        .flatMap {
            val newRequest = exchange.request.mutate()
                .headers { httpHeaders -> httpHeaders.set("sample", it) }
                .build()
            chain.filter(exchange.mutate().request(newRequest).build())
        }
}

逻辑说明

  • exchange.mutateToError().then(Mono.empty<String>()):先执行错误响应的写入操作(mutateToError()返回Mono<Void>),再通过then操作符切换到Mono.empty<String>(),保证与上游Mono<String>的类型一致性。
  • 由于返回的是空流,后续的flatMap不会被触发,后续链路的逻辑自然不会执行,完全符合“仅处理sample()错误,不捕获后续链路错误”的需求。

内容的提问来源于stack exchange,提问作者EnDorphin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:40:25