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

如何在RestSharp中细粒度区分并处理网络/服务器/序列化错误?

RestSharp细粒度错误处理方案咨询

我的RestSharp客户端代码

var opts = new RestClientOptions("http://api.muyservice.com/")
{
    // 反序列化失败时不将ResponseStatus设为Error
    FailOnDeserializationError = false,
};

using var client = new RestClient(opts);
var request = new RestRequest("myEndpoint");
var response = await client.ExecuteAsync<ResponseDto>(request);

// 错误处理逻辑
// 网络错误?无法直接区分
// 同时覆盖4xx/5xx状态码(404除外)
if (response.ResponseStatus != ResponseStatus.Completed) 
{
    // 记录网络错误
}
else if (response.StatusCode != HttpStatusCode.OK)
{
    // HTTP请求完成,但服务器返回非200结果
    // 处理服务器错误
    if (response.StatusCode == HttpStatusCode.BadRequest)
    {
        // 从响应体提取错误详情
    }
    else
    {
        // 处理通用服务器错误
    }
}
else if (response.Data == null)
{
    // 序列化失败
}
else
{
    // 一切正常,处理结果
}

遇到的问题

我希望对网络、服务器和序列化错误做差异化的细粒度处理(比如记录不同细节、请求超时时提示调整配置),但目前遇到以下阻碍:

  • 网络错误或服务器返回4xx/5xx(除404外)时,response.ResponseStatus都会变为Error,无法直接区分两类错误
  • 请求超时后,ResponseStatus为TimedOut,但ErrorMessage和ErrorException仅显示“Operation was canceled”,未明确标注是超时导致
  • IsSuccessfulStatusCode会将HTTP 404判定为成功状态
  • 无专门的序列化错误状态标识,若ResponseDto允许null作为有效值,完全无法判断是否是序列化失败导致的null

请问RestSharp中有没有直接实现细粒度错误处理的方法?


解决方案

1. 区分网络错误与HTTP错误

RestSharp中,网络类错误(如连接失败、DNS解析失败、超时)会导致ResponseStatus变为TimedOut/Aborted/Error,且StatusCode为0;而HTTP错误(4xx/5xx)的ResponseStatus始终是Completed,同时StatusCode会对应具体的HTTP状态码。

调整判断逻辑即可区分:

if (response.ResponseStatus != ResponseStatus.Completed) {
    // 处理网络类错误
    if (response.ResponseStatus == ResponseStatus.TimedOut) {
        // 专门处理超时:记录并提示调整超时配置
        Console.WriteLine("请求超时,建议修改RestClientOptions.Timeout参数");
    } else {
        // 其他网络错误:比如连接失败、DNS异常等
        var exception = response.ErrorException;
        // 记录异常堆栈等详情
    }
} else {
    // HTTP请求已完成,处理状态码逻辑
    bool isExpectedSuccess = response.StatusCode == HttpStatusCode.OK;
    if (!isExpectedSuccess) {
        // 处理4xx/5xx错误
        if (response.StatusCode == HttpStatusCode.NotFound) {
            // 单独处理404场景
        } else {
            // 提取服务器返回的错误响应体
            var errorContent = response.Content;
        }
    }
}

2. 明确识别超时错误

RestSharp的超时本质是触发TaskCanceledException,可通过ErrorException的类型和取消标记判断:

if (response.ResponseStatus == ResponseStatus.TimedOut) {
    if (response.ErrorException is TaskCanceledException tce && !tce.CancellationToken.IsCancellationRequested) {
        // 这是真正的超时,而非手动取消请求
        Console.WriteLine($"请求超时,当前超时配置:{opts.Timeout}毫秒");
    }
}

3. 自定义成功状态码判断

不要依赖内置的IsSuccessfulStatusCode,自己定义符合业务需求的判断逻辑:

bool IsExpectedSuccess(HttpStatusCode code) {
    // 只把200视为成功,可根据业务调整
    return code == HttpStatusCode.OK; 
}

// 使用示例
if (IsExpectedSuccess(response.StatusCode)) {
    // 处理成功逻辑
} else {
    // 处理HTTP错误
}

4. 检测序列化错误

由于设置了FailOnDeserializationError = false,序列化失败时Data会为null,但如果ResponseDto允许null,可通过response.ErrorException判断——序列化失败时该属性会包含序列化器抛出的异常(如JsonSerializationException):

if (response.ResponseStatus == ResponseStatus.Completed && IsExpectedSuccess(response.StatusCode)) {
    if (response.Data == null) {
        // 检查是否存在序列化异常
        if (response.ErrorException != null && response.ErrorException.GetType().Name.Contains("Serialization")) {
            // 处理序列化错误:记录异常信息、重试等
        } else {
            // 服务器确实返回了null有效值
        }
    } else {
        // 正常处理返回数据
    }
}

额外建议:封装错误处理扩展方法

可以把这些判断逻辑抽离成扩展方法,避免重复代码:

public static class RestResponseExtensions {
    public static bool IsNetworkError(this RestResponse response) {
        return response.ResponseStatus != ResponseStatus.Completed;
    }

    public static bool IsTimeoutError(this RestResponse response) {
        return response.ResponseStatus == ResponseStatus.TimedOut 
            && response.ErrorException is TaskCanceledException tce 
            && !tce.CancellationToken.IsCancellationRequested;
    }

    public static bool IsSerializationError(this RestResponse response) {
        return response.ResponseStatus == ResponseStatus.Completed 
            && response.StatusCode == HttpStatusCode.OK 
            && response.Data == null 
            && response.ErrorException != null 
            && response.ErrorException.GetType().Name.Contains("Serialization");
    }
}

使用时只需直接调用:

if (response.IsNetworkError()) {
    if (response.IsTimeoutError()) {
        // 处理超时
    } else {
        // 处理其他网络错误
    }
} else if (!IsExpectedSuccess(response.StatusCode)) {
    // 处理HTTP错误
} else if (response.IsSerializationError()) {
    // 处理序列化错误
} else {
    // 正常处理业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:43:24