Spring Gateway中flatMap返回Mono.error()时switchIfEmpty被执行问题
问题解析
switchIfEmpty只触发一种场景:上游Mono正常执行完成,但没有发射任何元素。而Mono.error()属于错误信号,按逻辑本不会触发switchIfEmpty。你遇到的异常时switchIfEmpty仍执行的情况,大概率是异常被偷偷转换成了空Mono——比如Redis连接超时、失败时,你的redisTemplate配置成返回空而非抛出错误,或者全局异常处理逻辑把错误信号转成了空响应。
正确实现方案
要达成「Redis返回值时抛出异常并终止流,Redis无值时执行somethingElse」的逻辑,直接用以下写法即可:
public Mono<Something> example() { return redisTemplate.opsForValue() .get(cacheKey) // Redis返回值时直接抛出异常 .flatMap(jsonString -> Mono.error(new RuntimeException("oops"))) // 仅当Redis无值(正常完成且无元素)时执行备选逻辑 .switchIfEmpty(somethingElse(cacheKey, token)); }
如果问题仍存在,排查这两个点:
- 检查
redisTemplate配置:确认是否将Redis操作异常(如连接失败、超时)转换成了空Mono,正常场景下这类异常应该直接抛出。 - 检查全局异常处理:是否存在把
Mono.error()转换为空Mono的逻辑。
要是担心有异常被意外转换,可添加onErrorResume强制传递错误信号:
public Mono<Something> example() { return redisTemplate.opsForValue() .get(cacheKey) .flatMap(jsonString -> Mono.error(new RuntimeException("oops"))) .switchIfEmpty(somethingElse(cacheKey, token)) // 捕获所有异常,直接重新抛出,确保不触发备选逻辑 .onErrorResume(Throwable.class, Mono::error); }
内容的提问来源于stack exchange,提问作者Saikiran
相关产品推荐
相关产品推荐

