Flurl错误处理

2058 更新于: 2021-03-15 读完约需 4 分钟

错误处理(Error Handling)

不像HttpClient, 默认情况下Flurl.Http会抛出任何非2xx的Http状态,以下是原因:

  • 非2xx情况往往是“异常的”,也就是说,在“正常”的环境和逻辑流中会是2xx状态,因此非2xx状态适合try/catch范式。
  • 特别是在JSON API中,错误响应体倾向于采用与常规响应不同的形状,并且如果您使用如url.GetJsonAsync<RegularShape>()这样的快捷处理方法的话, Flurl的try/catch模式提供了一种反序列化到catch块中不同内容的方法,如下:
try {
    var result = await url.PostJsonAsync(poco).ReceiveJson<T>();
}
catch (FlurlHttpException ex) {
    var error = await ex.GetResponseJsonAsync<TError>();
    logger.Write($"Error returned from {ex.Call.Request.Url}: {error.SomeDetails}");
}

以上的调用属性是事件处理程序使用的同一个FlurlCall对象的实例,它提供了关于调用的丰富细节。对于简单的日志和调试,FlurlHttpException.Message提供了错误的简易摘要,包括URL、HTTP谓词和接收到的状态代码等等。

FlurlHttpException还提供了一些反序列化body的快捷方式:

Task<string> GetResponseStringAsync();
Task<T> GetResponseJsonAsync<T>();
Task<dynamic> GetResponseJsonAsync();

这些都是FlurlHttpException.Call上等效方法的简写,因此如果你需要获取例如流这样的不同数据,您可以使用该方式。

超时(Timeouts)

Flurl.Http为超时定义了一个特殊的异常类型:FlurlHttpTimeoutException,这种类型继承自FlurlHttpException,因此会在catch (FlurlHttpException)块中被捕获,同时,你也可以使用不同的方式来处理超时:

catch (FlurlHttpTimeoutException) {
    // 处理超时
}
catch (FlurlHttpException) {
    // 处理错误响应
}

除了FlurlHttpTimeoutException之外没有其他属性,但因为超时意味着没有收到响应,所有与响应相关的属性都将始终为null

默认超时是100秒(与HttpClient相同),但这可以在任何设置级别上配置,或者内联每个请求:

await url.WithTimeout(200).GetAsync(); // 超时时间设置成了200秒
await url.WithTimeout(TimeSpan.FromMinutes(10)).GetAsync();

允许非2xx响应

如果你不喜欢默认的抛出行为,你可以通过Settings.AllowedHttpStatusRange在任何设置级别更改它,这是一个基于字符串(除了通配符)的设置,所以如果你从来不想抛出,可将它设置为*

你也可以在请求级别允许非2XX:

url.AllowHttpStatus("400-404,6xx").GetAsync();
url.AllowAnyHttpStatus().GetAsync();

第一个示例中的模式是显而易见的,AllowHttpStatus()方法允许的字符包括数字、逗号(分隔符)、连字符(范围)和通配符xX*。这些语法规则与Settings.AllowedHttpStatusRange是相同的,但是有一个细微的行为差异:上面的请求级别方法是可添加的,所以,例如如果每个设置都允许2xx,你就不必在请求级别模式中包含它。

在反序列化前检查响应

如果你喜欢把非2xx状态作为正常控制流的一部分来处理,这很简单:

var response = await url
    .AllowAnyHttpStatus()
    .GetAsync();

if (result.StatusCode < 300) {
    var result = await response.GetJsonAsync<T>();
    Console.WriteLine($"Success! {result}")
}
else if (result.StatusCode < 500) {
    var error = await response.GetJsonAsync<UserErrorData>();
    Console.WriteLine($"You did something wrong! {error}")
}
else {
    var error = await response.GetJsonAsync<ServerErrorData>();
    Console.WriteLine($"We did something wrong! {error}")
}

这里的responseIFlurlResponse的一个实例,它封装了System.Net.Http.HttpResponseMessage信息,除了StatusCode之外,你还可以通过多种方式检查头部、cookie以及获取正文内容:

Task<T> GetJsonAsync<T>();
Task<dynamic> GetJsonAsync();
Task<IList<dynamic>> GetJsonListAsync();
Task<string> GetStringAsync();
Task<Stream> GetStreamAsync();
Task<byte[]> GetBytesAsync();

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

本文永久链接码友网 » Flurl中文文档(使用教程) » Flurl错误处理 分享:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册