Nic*_*rbé 5 spring spring-boot project-reactor spring-webflux
我正在使用WebFlux的功能端点.我使用onErrorResume
以下方法将服务层发送的异常转换为HTTP错误代码:
public Mono<String> serviceReturningMonoError() {
return Mono.error(new RuntimeException("error"));
}
public Mono<ServerResponse> handler(ServerRequest request) {
return serviceReturningMonoError().flatMap(e -> ok().syncBody(e))
.onErrorResume( e -> badRequest(e.getMessage()));
}
Run Code Online (Sandbox Code Playgroud)
一旦服务返回Mono,它就能很好地工作.如果服务返回Flux,我该怎么办?
public Flux<String> serviceReturningFluxError() {
return Flux.error(new RuntimeException("error"));
}
public Mono<ServerResponse> handler(ServerRequest request) {
???
}
Run Code Online (Sandbox Code Playgroud)
编辑
我尝试了下面的方法,但不幸的是它不起作用.Flux.error不会被onErrorResume
传播并传播到框架.当在http响应的序列化期间取消装箱异常时,Spring Boot异常管理会捕获它并将其转换为500.
public Mono<ServerResponse> myHandler(ServerRequest request) {
return ok().contentType(APPLICATION_JSON).body( serviceReturningFluxError(), String.class)
.onErrorResume( exception -> badRequest().build());
}
Run Code Online (Sandbox Code Playgroud)
我实际上对这个行为感到惊讶,那是一个bug吗?
您的第一个示例正在使用Mono
(即最多一个值),因此它运行良好Mono<ServerResponse>
- 该值将在内存中异步解析,并且根据结果,我们将返回不同的响应或手动处理业务异常。
如果是 a Flux
(即 0..N 值),则任何给定时间都可能发生错误。
在这种情况下,您可以使用collectList
运算符将您的内容转换Flux<String>
为 a Mono<List<String>>
,并带有一个大警告:所有元素都将缓冲在内存中。如果数据流很重要或者您的控制器/客户端依赖于流数据,那么这不是最佳选择。
恐怕我没有更好的解决方案来解决这个问题,原因如下:由于错误可能在 期间随时发生Flux
,因此不能保证我们可以更改 HTTP 状态和响应:事情可能已经在网络。InputStream
使用 Spring MVC 并返回 an或 a时已经是这种情况Resource
。
Spring Boot 错误处理功能尝试编写错误页面并更改 HTTP 状态(请参阅ErrorWebExceptionHandler
实现类),但如果响应已提交,它将记录错误信息并让您知道 HTTP 状态可能是错误的。
归档时间: |
|
查看次数: |
4403 次 |
最近记录: |