diff --git a/lib/context_dev/internal/transport/base_client.rb b/lib/context_dev/internal/transport/base_client.rb index c9754cfd..825a1cac 100644 --- a/lib/context_dev/internal/transport/base_client.rb +++ b/lib/context_dev/internal/transport/base_client.rb @@ -335,17 +335,17 @@ def initialize( private def retry_delay(headers, retry_count:) # Non-standard extension span = Float(headers["retry-after-ms"], exception: false)&.then { _1 / 1000 } - return span if span + return [span, 0.0].max if span retry_header = headers["retry-after"] - return span if (span = Float(retry_header, exception: false)) + return [span, 0.0].max if (span = Float(retry_header, exception: false)) span = retry_header&.then do Time.httpdate(_1) - Time.now rescue ArgumentError nil end - return span if span + return [span, 0.0].max if span scale = retry_count**2 jitter = 1 - (0.25 * rand) diff --git a/test/context_dev/client_test.rb b/test/context_dev/client_test.rb index d42cb820..fe329c0b 100644 --- a/test/context_dev/client_test.rb +++ b/test/context_dev/client_test.rb @@ -120,6 +120,27 @@ def test_client_retry_after_date assert_in_delta(10, Thread.current.thread_variable_get(:mock_sleep).last, 1.0) end + def test_client_retry_after_past_date + time_now = Time.now + + stub_request(:post, "http://localhost/web/scrape").to_return_json( + status: 500, + headers: {"retry-after" => (time_now - 60).httpdate}, + body: {} + ) + + context_dev = ContextDev::Client.new(base_url: "http://localhost", api_key: "My API Key", max_retries: 1) + + Thread.current.thread_variable_set(:time_now, time_now) + assert_raises(ContextDev::Errors::InternalServerError) do + context_dev.web.scrape(formats: {}, url: "https://example.com") + end + Thread.current.thread_variable_set(:time_now, nil) + + assert_requested(:any, /./, times: 2) + assert_equal([0.0], Thread.current.thread_variable_get(:mock_sleep)) + end + def test_client_retry_after_ms stub_request(:post, "http://localhost/web/scrape").to_return_json( status: 500,