在Spring webflux中的异常处理
原文链接:https://stackoverflow.com/questions/69231306/exception-handling-in-spring-webflux
问题描述
我在一个Spring webflux项目中使用reactive streams。
我有个例子如下,我想知道用reactive的方式该怎么做呢?
JAVA
@RestController
public class Example {
@GetMapping("/greet")
public Mono<String> Test() {
return Mono.just("Tim")
.map(s -> s.toUpperCase())
.map(s -> s.toLowerCase())
.doOnSuccess(s -> validate(s)) // usecase is to validate here in middle of the pipeline
.onErrorResume(ex -> Mono.just("Guest"))
.map(s -> "Hi, "+s);
}
public void validate(String s) {
if(s.length() < 5) {throw new RuntimeException("Name is short");}
}
}
我知道这是刻意写的例子,我有一些类似的代码。我想,当异常被触发时,抛出的异常会出现在浏览器上。但令我惊讶的是,它继续执行到了onErrorResume()
,并且响应了Hi, Guest
。我想在reactive pipeline被组装之前通过throw
抛出一个异常,而不让它执行到onErrorResume()
。我漏了什么了吗?
还有一个问题,我如何达到这个目的,如果我使用Mono.error(new RuntimeException("Name is short"))
而不是throw new RuntimeException("Name is short")
?
有人能回答我的2个问题吗?感谢改进代码的建议。
答案
我想在reactive pipeline被组装之前通过
throw
抛出一个异常,而不让它执行到onErrorResume()
。
当Mono
成功完成时(pipeline已经是装配完成状态),Mono::doOnSuccess
在运行时触发。
注意,这里面的中间操作符像doOnNext
或map
你可以任意抛出异常,因为Reactor能够将它们转变为合适的异常信号,因为Mono
已经在进程中了。
我如何达到这个目的,如果我使用
Mono.error(new RuntimeException("Name is short"))
而不是throw new RuntimeException("Name is short")
?
你可以替换doOnSuccess
和map
为handle
操作符:
JAVA
return Mono.just("Tim")
.handle((name, sink) -> {
if(name.length() < 5){
sink.error(new RuntimeException("Name is short"));
} else {
sink.next(name.toLowerCase());
}
})