如何在Flurl中处理“Bad Request”异常

8

我完全不了解Flurl。我正试图调用API,故意在参数中传递无效的ApiKey,然后API失败并显示“Forbidden”,并显示错误代码403。我该如何在异常中处理它?

 public async Task<myResponse> MyService(myRequest request)
    {
        try
        {


            return await new Flurl.Url("https://myapi.com/rest/age?apikey=XXXXXXXX").PostJsonAsync(apirequest).ReceiveJson<myResponse>();
        }
        catch (FlurlHttpException ex)
        {
            var statusCode = await ex.GetResponseJsonAsync<myResponse>();
            return await ex.GetResponseJsonAsync<myResponse>();

        }

如果我收到状态码403,我想抛出自定义异常,但目前代码在行 var statusCode = await ex.GetResponseJsonAsync<myResponse>(); 处失败。

1个回答

14
我希望在收到状态码403时抛出自定义异常。
有两种方法可以实现。第一种方法是在catch块中简单地重新抛出异常(catch/when在这里非常方便):
try
{
    ...
}
catch (FlurlHttpException ex) when (ex.Call.HttpStatus == HttpStatusCode.Forbidden)
{
    throw new MyException(...);
}

第二种方法是使用AllowHttpStatus来防止Flurl抛出异常:
var resp = await "https://myapi.com/rest/age?apikey=XXXXXXXX"
    .AllowHttpStatus("4xx")
    .PostJsonAsync(apirequest);

if (resp.StatusCode == HttpStatusCode.Forbidden)
{
    throw new MyException(...);
}

第二种方法有一个注意点,那就是你会得到一个“原始”的HttpResponseMessage,你需要自己进行反序列化,因为Flurl的ReceiveJson是基于Task<HttpResponseMessage>的,而你已经等待了该Task。但是自己进行反序列化并不难, 近期有一个计划中的增强功能将解决这个问题,或者你可以使用这个小技巧:
await Task.FromResult(resp).ReceiveJson<myResponse>();

说实话,我可能会选择第一种方法。{{FlurlHttpException}}有一些方便的方法,比如{{GetResponseJsonAsync}}可以让你反序列化错误主体,如果它是JSON格式的,或者{{GetResponseStringAsync}}如果你只需要原始字符串。

只是为了补充那个出色的答案 -- Flurl 还支持 AllowAnyHttpStatus() 选项。 - Dariusz Woźniak
".AllowHttpStatus("4xx")" 是指字面上的 'xx',还是应该被实际值替换,例如 ".AllowHttpStatus("400")" 或 ".AllowHttpStatus("403")"? - Alek Davis
1
@AlekDavis 中的 "x" 或 "*" 被视为通配符。https://flurl.dev/docs/error-handling/#allowing-non-2xx-responses - Todd Menier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接