错误处理(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()
方法允许的字符包括数字、逗号(分隔符)、连字符(范围)和通配符x
或X
或*
。这些语法规则与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}")
}
这里的response
是IFlurlResponse
的一个实例,它封装了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();
发表评论
登录用户才能发表评论, 请 登 录 或者 注册