Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Extensions.Http.Resilience: Unexpected default behaviour of Retry.DisableForUnsafeHttpMethods in combination with TimeoutRejectedException #6548

@edgar-tamm-uptime

Description

@edgar-tamm-uptime

Description

Hello,

https://learn.microsoft.com/en-us/dotnet/core/resilience/http-resilience?tabs=dotnet-cli#disable-retries-for-a-given-list-of-http-methods

Based on documentation added retry exception for unsafe http methods:

httpClientBuilder.AddStandardResilienceHandler(options =>
{
    options.Retry.DisableForUnsafeHttpMethods();
});

Recently found out that this still did retries when the http request method was unsafe when a TimeoutRejectionException happened.

Debugged and based on the code in DisableFor:

, the issue seems to be that during that timeout exception the args.Outcome.Result property is NULL so the code seemingly won't be able to determine what the request http method is.

Reproduction Steps

Configure a http client & resiliency as described in the documentation, call a service (with any of the unsafe http methods) which responds too late (more than the default 10s) so a TimeoutRejectionException happens.

A basic example:
Server:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapPost("/timeout", async () =>
{
    // Simulate processing longer than the default 10s timeout
    await Task.Delay(TimeSpan.FromSeconds(20));

    return Results.Ok();
});

app.Run();

Client:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Http.Resilience;

var app = Host.CreateDefaultBuilder()
    .ConfigureServices(services =>
    {
        services.ConfigureHttpClientDefaults(o =>
        {
            o.AddStandardResilienceHandler(o =>
            {
                o.Retry.DisableForUnsafeHttpMethods();
            });
        });

        services.AddHttpClient();
    })
    .Build();

var httpClient = app.Services.GetRequiredService<HttpClient>();
httpClient.BaseAddress = new Uri("http://localhost:5234");

// This will retry (if you look at the logs)
var result = await httpClient.PostAsync("/timeout", null);

Expected behavior

No retries happen, because it is a unsafe http method.

Actual behavior

Retries do happen.

Regression?

No response

Known Workarounds

No response

Configuration

.net 9
Extensions.Http.Resiliency - 9.0.6

Other information

No response

Metadata

Metadata

Labels

area-resiliencebugThis issue describes a behavior which is not expected - a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions