You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过HttpClient发送HttpRequestMessage,捕获异常时如何判断请求是否抵达目标?

更优的HttpClient请求重试判断方案

1. 基于响应状态码的核心判断逻辑

请求确实抵达服务器时,哪怕服务器中途崩溃,通常也会返回明确的5xx类状态码(如502、504),此时HttpRequestException的StatusCode不会为空。只有请求完全未发送成功(比如DNS解析失败、TCP连接建立失败),才会抛出无StatusCode的异常,这类场景可以安全重试。

2. 封装统一的异常判断工具

不用手动逐层拆解SocketException,可以写一个辅助方法集中处理异常判断:

public static bool IsRequestNotReachedServer(Exception ex)
{
    // 有状态码说明请求已抵达服务器
    if (ex is HttpRequestException httpEx && httpEx.StatusCode.HasValue)
    {
        return false;
    }
    
    // 逐层查找SocketException并判断错误码
    var innerEx = ex.InnerException;
    while (innerEx != null)
    {
        if (innerEx is SocketException socketEx)
        {
            // 这些错误码代表请求未成功发送
            return socketEx.SocketErrorCode is SocketError.ConnectionRefused 
                or SocketError.HostNotFound 
                or SocketError.TimedOut 
                or SocketError.NoData;
        }
        innerEx = innerEx.InnerException;
    }
    
    // 未知异常默认按未抵达处理(可根据业务调整)
    return true;
}

3. 借助成熟重试库简化逻辑

用Polly这类重试库的内置策略,能自动区分「可重试的网络异常」和「服务器已处理的请求」,不用自己写复杂的判断逻辑:

var retryPolicy = Policy
    .Handle<HttpRequestException>(ex => !ex.StatusCode.HasValue)
    .Or<SocketException>(ex => ex.SocketErrorCode is SocketError.ConnectionRefused or SocketError.HostNotFound)
    .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

// 用策略包裹请求执行
await retryPolicy.ExecuteAsync(async () =>
{
    using var response = await httpClient.SendAsync(request);
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync();
});

4. 幂等标识兜底方案

如果无法100%确定请求是否抵达,最稳妥的方式是给每个请求添加幂等键(比如在请求头里加Idempotency-Key)。服务器端通过这个键识别重复请求,返回相同结果,避免重复操作。这是从根源上规避重试风险的方案,比单纯判断异常更可靠。


内容的提问来源于stack exchange,提问作者devvy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 05:25:01