使用Mutiny时onItem执行后仍触发onFailure的原因咨询
Mutiny拆分成功/失败分支时触发异常分支的问题分析
你遇到的问题核心是对Mutiny操作符的链式调用逻辑理解有误,具体是搞错了replaceWith()的作用范围。
先看你的代码:
@GET @Path("/test") @Produces(MediaType.APPLICATION_JSON) public Uni<RestResponse<?>> test() { return Uni.createFrom().item("Hello world") .onItem().transform(str -> { var resp = RestResponse.ok(str); System.out.println("In onItem"); return resp; }) .onFailure().recoverWithNull().replaceWith(() -> { System.out.println("In onFailure"); return RestResponse.status(500); }); }
这里的.onFailure().recoverWithNull()确实是针对失败场景的处理,但后续的.replaceWith()并不是onFailure分支的一部分——它是作用于整个Uni的全局操作,不管前面的Uni是成功返回结果,还是经过recoverWithNull()返回null,最终都会执行replaceWith()里的逻辑,把结果替换成500响应。这就是为什么你看到In onItem打印后,In onFailure也会打印,并且Postman返回500。
要实现“成功走200,失败走500”的需求,正确的写法是用onFailure().recoverWithItem()单独处理失败分支,而非在recoverWithNull()后接replaceWith():
@GET @Path("/test") @Produces(MediaType.APPLICATION_JSON) public Uni<RestResponse<?>> test() { return Uni.createFrom().item("Hello world") .onItem().transform(str -> { var resp = RestResponse.ok(str); System.out.println("In onItem"); return resp; }) .onFailure().recoverWithItem(failure -> { System.out.println("In onFailure"); return RestResponse.status(500); }); }
修改后逻辑就正常了:
- 当Uni成功时,只会触发
onItem().transform()分支,返回200响应,不会进入失败处理逻辑 - 当Uni真的发生失败时,才会触发
onFailure().recoverWithItem()分支,返回500响应
另外补充一种写法:如果想用replaceWith()处理失败场景,需要把它放在onFailure()的分支内,效果和recoverWithItem()一致:
.onFailure().replaceWith(() -> { System.out.println("In onFailure"); return RestResponse.status(500); })
内容的提问来源于stack exchange,提问作者Gert Kommer
相关产品推荐
相关产品推荐

