我正在尝试使用 Spring 的 WebClient 从 REST 服务检索数据,并尝试将 4XX 和 5XX 放入
Error
而不是 RuntimeException
中。
return webclient.
.get()
.uri(myURI)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatus::isError, handleError()
.bodyToMono(String.class)
.block();
private static Function<ClientResponse, Mono<? extends Throwable>> handleError() {
return response -> response.bodyToMono(String.class).map(CustomError::new);
}
我试图在测试中获得此
Error
,但收到的是 ReactiveException
。
org.opentest4j.AssertionFailedError: Unexpected exception type thrown,
Expected :class com.example.CustomError
Actual :class reactor.core.Exceptions$ReactiveException
当我将
CustomError
的扩展名从 Error
切换到 RuntimeException
时,测试通过。
由于 onStatus 除外
Function<ClientResponse, Mono<? extends Throwable>>
我希望能够在此调用中抛出错误。
我正在开发一个测试库,并且初始请求是绝对必要的,如果没有成功的请求,测试必定会失败。
Error
将防止任何人在自己的测试中发现与 REST 请求相关的任何问题。
您可能想尝试退回
Mono.error(new CustomError(response));
在您的 handleError()
方法中。
通过这种方式,您可以让反应式管道知道发生了错误以及之后要抛出什么。现在,您只需映射到一个 Error 对象,该对象的处理方式与 RuntimeExceptions 的处理方式不同。
我还想说,坚持使用
Exceptions
而不是 Errors
可能会更好。错误往往是程序运行时无法恢复的情况(例如OutOfMemoryError
),而异常只是可能可能做出反应的异常情况(重试 503 状态代码,或在收到 401 状态代码时重新进行身份验证)回来)。
实施示例
public Mono<? extends Throwable> handleError(ClientResponse clientResponse) {
String message = String.format("Service error: %s",
clientResponse.statusCode().getReasonPhrase());
return Mono.error(new CustomError(message));
}
这也是一个很好的答案:Reactor 抛出异常的正确方法