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
相关产品推荐
相关产品推荐

