【问题标题】:Flurl throws FlurlHttpException instead of FlurlHttpTimeoutExceptionFlurl 抛出 FlurlHttpException 而不是 FlurlHttpTimeoutException
【发布时间】:2020-04-29 09:47:33
【问题描述】:

我需要将超时作为特殊情况处理,但 flurl 在某些情况下不会给我预期的异常。

这是我的简化代码。

try
{           
    // Call Listener here with the result of the process
    using (IFlurlClient flurlClient = new FlurlClient(Url))
    {
        string response = await flurlClient
            .Configure(s => s.Timeout = TimeSpan.FromSeconds(130))
            .WithOAuthBearerToken(accessToken)
            .Request()
            .PostJsonAsync(result)
            .ReceiveString();

        Logger.LogInformation(response);
        ListenerResponse listenerResponse = JsonConvert.DeserializeObject<ListenerResponse>(response);
        Logger.LogInformation(listenerResponse.Success.ToString());

        if (!listenerResponse.Success)
        {
            throw new RejectedException("Listener rejected the request.");
        }
    }
}
catch (FlurlHttpTimeoutException ex)
{
    // throws with this message: "Call timed out: POST https://..."
    Logger.LogError(ex, $"Could not reach to Listener at: {Url}.");
    throw;
}
catch (FlurlHttpException ex)
{
    // throws with this message: "Call failed. Connection timed out POST https://..."
    Logger.LogError(ex, ex.Message); 
    throw;
}

发生的情况是,当我将超时设置为低于某个值 () 时,Flurl 会抛出预期的 FlurlHttpTimeoutException。但是,如果我将超时设置为高于该值(>=130),这次 flurl 会抛出更通用的FlurlHttpException

请注意,异常消息略有不同:

FlurlHttpTimeoutException

调用超时:POST https://...

FlurlHttpException

调用失败。 POST https://...

连接超时

有谁知道如何修复它以使其按预期运行 - 为所有超时值抛出 FlurlHttpTimeoutException

【问题讨论】:

  • >130 时,FlurlHttpException.InnerException 的类型/详细信息是什么?另外,这是一个 Xamarin/Android 项目吗?
  • 我偶然发现了让它工作的诀窍,那就是SocketHttpHandler.PooledConnectionLifetime。当我将它增加到 130 以上时,它开始抛出正确的异常。这是一个适用于 aws lambdas 的 dotnet core 2.1 项目。

标签: c# timeout flurl


【解决方案1】:

我最终做了这样的事情来解决这个问题,不确定这是否是解决问题的正确方法,但它成功了。

/// <summary>
/// Gets a flurl client
/// </summary>
/// <returns></returns>
private IFlurlClient GetFlurlClient()
{
    return new FlurlClient(new HttpClient(new SocketsHttpHandler
    {
        PooledConnectionLifetime = TimeSpan.FromSeconds(ListenerTimeout + 10)
    })
    {
        BaseAddress = new Uri(ListenerUrl)
    })
        .Configure(s => s.Timeout = TimeSpan.FromSeconds(ListenerTimeout));
}

【讨论】:

  • @Todd Menier,你能确认这是一个有效的解决方法吗?它确实可以解决问题,但不确定我是否在这里引入任何副作用。
  • 副作用是您从 Flurl 中控制了 FlurlClient 实例管理(但看起来您可能还是想自己管理),并且您将失去伪造的能力测试中的 HTTP 调用。我建议改用factory
  • 好建议,我会改变它以利用工厂,反正看起来更可靠。虽然令人困惑的是我所有的单元测试仍然通过(我多次伪造HttpTest 这个方法)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 2019-12-12
  • 1970-01-01
相关资源
最近更新 更多