// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Net;
using System.Net.Http;
using Microsoft.Shared.Diagnostics;
using Polly;
using Polly.Timeout;
namespace Microsoft.Extensions.Http.Resilience;
///
/// Provides static predicates used within the current package.
///
public static class HttpClientResiliencePredicates
{
///
/// Determines whether an outcome should be treated by resilience strategies as a transient failure.
///
/// if outcome is transient, if not.
public static bool IsTransient(Outcome outcome) => outcome switch
{
{ Result: { } response } when IsTransientHttpFailure(response) => true,
{ Exception: { } exception } when IsTransientHttpException(exception) => true,
_ => false
};
///
/// Determines whether an exception should be treated by resilience strategies as a transient failure.
///
internal static bool IsTransientHttpException(Exception exception)
{
_ = Throw.IfNull(exception);
return exception is HttpRequestException ||
exception is TimeoutRejectedException;
}
///
/// Determines whether a response contains a transient failure.
///
/// The current handling implementation uses approach proposed by Polly:
/// .
///
internal static bool IsTransientHttpFailure(HttpResponseMessage response)
{
_ = Throw.IfNull(response);
var statusCode = (int)response.StatusCode;
return statusCode >= InternalServerErrorCode ||
response.StatusCode == HttpStatusCode.RequestTimeout ||
statusCode == TooManyRequests;
}
private const int InternalServerErrorCode = (int)HttpStatusCode.InternalServerError;
private const int TooManyRequests = 429;
}