Ocelot icon indicating copy to clipboard operation
Ocelot copied to clipboard

ArgumentException when using QoSOptions with only TimeoutValue set

Open bNobo opened this issue 4 years ago • 3 comments

Expected Behavior / New Feature

According to documentation, it should be possible to set only TimeoutValue in QoSOptions.

Actual Behavior / Motivation for New Feature

When setting only TimeoutValue in QoSOptions, an ArgumentException occurs:

System.ArgumentException: The enumerable of policies to form the wrap must contain at least two policies. (Parameter 'policies')
         at Polly.Policy.WrapAsync(IAsyncPolicy[] policies)
         at Ocelot.Provider.Polly.PollyCircuitBreakingDelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
         at Ocelot.Requester.HttpClientHttpRequester.GetResponse(HttpContext httpContext) errors found in ResponderMiddleware. Setting error response for request path:/httpbin/alice, request method: POST

When adding ExceptionsAllowedBeforeBreaking and DurationOfBreak the exception disappears. I have this exception since I've upgraded from v15.0.0 to v17.0.0 and installed Ocelot.Provider.Polly.

Steps to Reproduce the Problem

  1. Create a new ASP.Net Core 5 empty project (uncheck https and docker support)
  2. Install Ocelot v17.0.0
  3. Install Ocelot.Provider.Polly v17.0.0
  4. Modify Program.cs to load ocelot.json, for instance:
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>()
                        .ConfigureAppConfiguration((hostingContext, config) =>
                        {
                            config
                                .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                                .AddJsonFile("appsettings.json", true, true)
                                .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
                                .AddJsonFile("ocelot.json", optional: false, reloadOnChange: true)
                                .AddJsonFile($"ocelot.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
                        });
                });
  1. Modify Startup.cs to add Ocelot and Polly:
public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddOcelot()
                .AddPolly();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseOcelot()
                .Wait();
        }
    }
  1. Add an ocelot.json file containing:
{
  "Routes": [
    {
      "DownstreamPathTemplate": "/anything/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "httpbin.org",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/httpbin/{everything}",
      "UpstreamHttpMethod": [ "Post" ],
      "QoSOptions": {
        //"ExceptionsAllowedBeforeBreaking": 1,
        //"DurationOfBreak": 1000,
        "TimeoutValue": 110000
      }
    }
  ]
}
  1. Start the application and make a POST to http://localhost:5000/httpbin/alice using your favorite REST client
  2. Notice you get an HTTP Status 500 Internal Server Error and the application console contains an ArgumentException
  3. Open ocelot.json and uncomment ExceptionsAllowedBeforeBreaking and DurationOfBreak settings under QoSOptions section
  4. make a POST to http://localhost:5000/httpbin/alice
  5. Notice you get an HTTP Status 200 OK response

Specifications

  • Version: 17.0.0
  • Platform: Windows and Linux (tested on both)
  • Subsystem: .NET 5

bNobo avatar May 25 '21 12:05 bNobo

Looks like this PR should fix the problem: https://github.com/ThreeMammals/Ocelot/pull/1279

The documentation even says you can set the Timeout option on its own but it breaks it :\ image

LukePammant avatar Oct 01 '21 19:10 LukePammant

I also ran into this issue today. #908 describes the same issue and as @LukePammant already mentioned, there is a PR that would fix this. Would be great to have this fix.

In the mean time the workaround is to simply add all three options as described in step 6/8 of this issue.

eddex avatar Dec 03 '21 12:12 eddex

Oh hello. I ran into this issue again today using v18.0.0 and ended up finding this issue again. :)

Would be great if PR https://github.com/ThreeMammals/Ocelot/pull/1279 would be merged and a new version could be created.

eddex avatar Aug 23 '22 08:08 eddex

This issue is still not fixed

kamil467 avatar Nov 28 '22 14:11 kamil467

Dear community, The PR #1279 had been merged on on Sep 22, 2023 I hope this issue is not reproducible anymore. Going to close...

raman-m avatar Jan 06 '24 12:01 raman-m