Con*_*eer 4 spring exception spring-webflux
我正在开发一个项目,我们正在从 迁移RestTemplate
到WebClient
.
是WebClient
这样实现的:
try {
...
return webClient
.get()
.uri(someUri)
.retrieve()
.toEntity(SomeBusinessClass.class).block()
} catch(WebClientException e) {
// do some stuff
// want to catch IOExceptions here as well
}
Run Code Online (Sandbox Code Playgroud)
在重构代码时,我也必须重构测试,我遇到了一个测试,在该测试中我们基本上抛出一个ConnectException
来看看我们的内部代码是否根据我们的需要捕获它们。通过RestTemplate
的异常类,我们能够像这样定义异常:
ResourceAccessException exc = new ResourceAccessException("I/O error on GET request", new ConnectException("Connection refused: connect"))
Run Code Online (Sandbox Code Playgroud)
WebClient
我尝试对提供的异常类执行相同的操作WebClientException
,但这是一个抽象类,唯一继承它的类WebClientResponseException
并且不提供允许执行相同操作的构造函数。所以我唯一的选择是这样做RuntimeException
:
RuntimeException exc = new RuntimeException("I/O error on GET request", new ConnectException("Connection refused: connect"))
Run Code Online (Sandbox Code Playgroud)
但是,由于我不想重写我们的内部代码来捕获RuntimeException
级别上的异常WebClientException
,所以这不是一个选项,我想知道如何做到这一点?
我试图在 Spring 文档中找出如何IOException
在使用时处理 's WebClient
,但找不到任何东西。
这里的方法是什么?
最好的方法几乎肯定是处理反应流本身中的所有错误。服务器响应错误通常最好通过使用exchange()
而不是retrieve()
然后手动处理响应来处理,并且底层IOException
使用onErrorResume()
等onErrorReturn()
可用于此目的的反应性运算符。
但是,您提到您正在从阻止代码迁移,所以我知道实际上这可能(尚未)出现在卡片上。如果你想坚持捕获异常:
但由于我不想重写我们的内部代码来捕获 RuntimeException 级别的异常,而是捕获 WebClientException 级别的异常,所以这不是一个选项,我想知道如何做到这一点?
想要捕获所有传输错误WebClientException
并不是一个明智的选择。正如你所说,两者都不是RuntimeException
出于显而易见的原因而被抓住的。
简化它,WebClientException
意味着“我连接到该 URL 并向其发送内容,没有出现任何问题,但它告诉我滚开”(即,它生成了错误代码而不是 200 响应。)
这可能是因为 404(未找到资源)、500(服务器错误)、418(您正在尝试连接到茶壶,而不是服务器)等。
IOException
另一方面意味着“甚至无法建立与此 URL 的连接”。可能是因为连接被主动拒绝、域名无法解析、SSL证书过期等。
两者并不相似,这样对待它们会显得相当奇怪和令人困惑。
如果你想在同一个块中处理它们,那就没问题了——你可能会天真地这样做:
catch(WebClientException|IOException e) {
// do some stuff
}
Run Code Online (Sandbox Code Playgroud)
...但你当然不能,因为IOException
经过检查。(Java 中的反应式流不会抛出已检查异常,每个已检查异常都会映射到 a RuntimeException
。)
但是,您可以将所有内容映射IOException
到UncheckedIOException
:
return webClient
.get()
.uri(someUri)
.retrieve()
.toEntity(SomeBusinessClass.class)
.onErrorMap(IOException.class, UncheckedIOException::new)
.block()
Run Code Online (Sandbox Code Playgroud)
...然后要么执行catch(WebClientException|UncheckedIOException ex)
,要么在单独的 catch 块中处理它们。
这当然不是处理反应性思维异常的“好”方法,但如果您的目标是以尽可能少的更改进行迁移,那么这可能就是您所追求的。
归档时间: |
|
查看次数: |
3465 次 |
最近记录: |