RestSharp GetAsync 忽略响应错误状态码

问题描述 投票:0回答:1

对RestSharp的评论 GetAsync<> 方法明确提到的。

用GET HTTP方法执行请求。如果请求不成功,将抛出异常。

我不知道该如何解释。我希望当返回一个非成功的HTTP状态码时,它会抛出一个异常。但事实似乎并非如此。当返回404或500状态时,该方法很高兴地尝试反序列化响应。只有当响应体包含无效的json(或xml,或任何被 "接受 "的东西)时,才会抛出一个错误。

我是不是遗漏了什么?我应该如何,使用这些异步方法,处理这样的错误响应?

error-handling restsharp http-status-codes
1个回答
0
投票

这个行为把我也吓到了。

从源码上看 RestClientExtensions在GitHub上జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ GetAsync方法被实现为。

public static async Task<T> GetAsync<T>(this IRestClient client, IRestRequest request, CancellationToken cancellationToken = default)
{
    var response = await client.ExecuteGetAsync<T>(request, cancellationToken);
    ThrowIfError(response);
    return response.Data;
}

你会认为 ThrowIfError会看HTTP状态码,但看的是 RestSharp错误处理文档,它说。

如果出现网络传输错误(网络瘫痪,DNS查找失败等),RestResponse.ResponseStatus将被设置为ResponseStatus.Error,否则将是ResponseStatus.Completed。

如果API返回的是404,ResponseStatus还是会是Completed。

你可以通过查看 ThrowIfError 实施。

static void ThrowIfError(IRestResponse response)
{
    var exception = response.ResponseStatus switch
    {
        ResponseStatus.Aborted   => new WebException("Request aborted", response.ErrorException),
        ResponseStatus.Error     => response.ErrorException,
        ResponseStatus.TimedOut  => new TimeoutException("Request timed out", response.ErrorException),
        ResponseStatus.None      => null,
        ResponseStatus.Completed => null,
        _                        => throw response.ErrorException ?? new ArgumentOutOfRangeException()
    };

    if (exception != null)
        throw exception;
}

至于你的问题:

我应该如何,使用这些异步方法, 处理这样的错误响应?

你不能:(。

我相信你必须实现自己的异步实现 Get<T>.

下面是我做的一个例子。

private Task<T> GetAsync<T>(RestRequest request)
{
    return Task.Run(() =>
    {
        var response = client.Get<T>(request);
        if (response.IsSuccessful)
            return response.Data;

        //handle the errors as you wish. In my case, the api I work with always
        //returns a bad request with a message property when it occurs...
        var errorData = JsonConvert.DeserializeObject<ApiMessage>(response.Content);
        throw new Exception(errorData.Message);
    });
}

public class ApiMessage
{
    public string Message { get; set; }
}

用法:

public Task<MyModel> SomeRequest()
{
    var request = new RestRequest()
    {
        Resource = "some-resource",
    };

    return GetAsync<MyModel>(request);
}

来源:

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.