// 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; }