c# 在WebClient 请求期间发生异常
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 在WebClient 请求期间发生异常相关的知识,希望对你有一定的参考价值。
代码:
程序运行:
错误:
断点显示:
何解?
请修改 app.manifest 设置 requestedExecutionLevel 为 requireAdministrator。 参考技术B 以上代码经测验,第一次点击不会出错,图片会下载到,
如果你第二次点击才会出错,这是因为你已经存在这张图片了,再下载后的图片与现有文件同名,所以报错。 参考技术C 不要放在C盘,C盘有权限的要求的。追问
你真的确定你会编程?
追答不多说,上图。
c 盘
D盘
我已经找到问题所在了,谢谢,之前不应该丢一个敲门砖WebRequest
本回答被提问者采纳使用带有阻塞/同步请求的 Spring WebClient 使用 try/catch 捕获异常
【中文标题】使用带有阻塞/同步请求的 Spring WebClient 使用 try/catch 捕获异常【英文标题】:Catch exceptions with try/catch using Spring's WebClient with blocking/syncronous request 【发布时间】:2020-11-07 17:24:44 【问题描述】:我需要发出 同步、阻塞 请求,我使用 Spring 的 WebClient
而不是 Spring 的 RestTemplate
,因为后者已被弃用。在这种情况下,我不需要响应式功能,我只想以直接的方式使用 REST API,而不包含额外的依赖项。
我有以下代码,按预期工作:
MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.bodyToMono( MyObject.class )
.block()
但是,当我无法连接到 API 或连接但我得到 4xx/5xx 代码时,我需要管理这些情况。
因此,直接的方法是将调用放在 try/catch 中,然后捕获 Spring 的 WebClientResponseException
,如果它获得 4xx/5xx 代码,则由 .bodyToMono
抛出:
import org.springframework.web.reactive.function.client.WebClientResponseException;
try
MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.bodyToMono( MyObject.class )
.block()
catch ( WebClientResponseException e )
// Logic to handle the exception.
这可以正常工作,但如果连接被拒绝(例如,如果 URL 错误或服务已关闭)则不起作用。在这种情况下,我在控制台中得到以下信息:
reactor.core.Exceptions$ErrorCallbackNotImplemented: io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) 失败:连接被拒绝:/127.0.0.1:8090 导致 作者:io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) 失败:连接被拒绝:/127.0.0.1:8090 抑制:reactor.core.publisher.FluxOnAssembly$OnAssemblyException:错误有 在以下站点观察到: |_ 检查点 ⇢ 请求 GET http://127.0.0.1:8090/test [DefaultWebClient] 堆栈跟踪:引起:java.net.ConnectException: finishConnect(..) 失败:连接被拒绝 在 io.netty.channel.unix.Errors.throwConnectException(Errors.java:124) ~[netty-transport-native-unix-common-4.1.48.Final.jar:4.1.48.Final] (...)
我不确定我需要捕获哪个异常来处理这种情况。
除了上述之外,如果连接被拒绝,我还想抛出一个自定义异常,如果我收到错误代码,我想抛出一个不同的自定义异常。在第二种情况下,我尝试使用.onStatus
方法:
try
MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.onStatus( HttpStatus::is4xxClientError, response ->
return Mono.error( new CustomClientException( "A client error ocurred" ) );
)
.bodyToMono( MyObject.class )
.block()
catch ( CustomClientException e )
// Logic to handle the exception.
但异常并未在 catch 块内捕获,尽管堆栈跟踪确实出现在控制台上。
有没有办法使用 try/catch 块来处理 4xx/5xx 代码和连接错误,希望有自定义异常?或者我应该使用不同的网络客户端和/或改变我的方法?我不熟悉反应式编程。
提前致谢。
【问题讨论】:
您需要ConnectException
才能处理此案。
如果您立即使用block()
,为什么还要使用WebClient
?
@Amitkumar,我尝试捕获 ConnectException
,但我收到一个编译器错误,提示它永远不会被抛出到 try 块中。
@chrylis-cautiouslyoptimistic- 因为 RestTemplate
在 Spring 5 中被弃用,所以文档推荐使用 WebClient
,它支持阻塞和非阻塞请求。我知道使用 block()
不会获得任何性能优势,但我认为在这种情况下这不一定是错误的,并且将来总有机会重构代码。
我认为将大块代码包装在单个 try catch 块中是不好的做法。您应该单独处理 WebClient
的异常,并且“其他逻辑”应该有自己的 try catch 块来处理它们的“问题”。
【参考方案1】:
使用retrieve()
,在底层HTTP 客户端上发生的所有异常都包装在一个名为ReactiveException
的RuntimeException
中。这样做是为了通过响应式接口冒泡检查的异常。
提供了一种在Exceptions.unwrap()
中获取实际包装异常的方法。然后,您可以抛出未包装的异常,稍后可以在适当的时候捕获它。一种方法可能如下:
void makeHttpCall(..) throws Exception
try
// ..
// webclient request code
// ..
catch(Exception e)
throw Exceptions.unwrap(e);
// somewhere else:
try
makeHttpCall(..);
catch (ConnectException e)
// Do your specific error handling
我不太喜欢用throws Exception
声明一个方法,但目前还不知道它可能是什么。
【讨论】:
显然unwrap
不会抛出Exception
,而是Throwable
,所以我不得不稍微改变你的例子,但它确实有效。就像你说的,我也不喜欢抛出通用异常,这样做感觉有点笨拙,所以我认为最好硬着头皮重构代码以正确的反应方式处理异常。不过,我接受你的回答,因为它直接回答了我的问题。非常感谢:)
如果您的异常是 RuntimeException 的子异常,则无需解包。请参考projectreactor.io/docs/core/snapshot/reference/#which.errors中的.onErrorMap
部分以上是关于c# 在WebClient 请求期间发生异常的主要内容,如果未能解决你的问题,请参考以下文章
反射:修改请求头HttpWebRequest/Webclient Header属性的date值-"此标头必须使用适当的属性进行修改"