diff --git a/pkg/providers/error_classifier_test.go b/pkg/providers/error_classifier_test.go index 810561fdb..4c3dd9314 100644 --- a/pkg/providers/error_classifier_test.go +++ b/pkg/providers/error_classifier_test.go @@ -139,8 +139,10 @@ func TestClassifyError_TimeoutPatterns(t *testing.T) { "connection timed out", "deadline exceeded", "context deadline exceeded", + "connection reset", "connection reset by peer", "tls handshake timeout", + "EOF", } for _, msg := range patterns { diff --git a/pkg/utils/llm_retry.go b/pkg/utils/llm_retry.go index 737cc0ab2..dabf2a15b 100644 --- a/pkg/utils/llm_retry.go +++ b/pkg/utils/llm_retry.go @@ -43,7 +43,7 @@ type RetryPolicy struct { Jitter RetryJitterFunc } -var retryAfterPattern = regexp.MustCompile(`(?i)retry[- ]after[:=]?\s*([^\s\r\n]+)`) +var retryAfterPattern = regexp.MustCompile(`(?i)retry[- ]after[:=]?\s*([^\r\n]+)`) // DefaultLLMRetryPolicy returns the default retry behavior for LLM calls. func DefaultLLMRetryPolicy() RetryPolicy { @@ -101,7 +101,7 @@ func DoWithRetry[T any](ctx context.Context, policy RetryPolicy, fn func(context sleepFn := policy.Sleep if sleepFn == nil { - sleepFn = sleepWithContext + sleepFn = sleepWithCtx } jitterFn := policy.Jitter if jitterFn == nil { @@ -232,18 +232,6 @@ func boundedAttemptTimeout(ctx context.Context, configured time.Duration) (time. return configured, true } -func sleepWithContext(ctx context.Context, d time.Duration) error { - timer := time.NewTimer(d) - defer timer.Stop() - - select { - case <-ctx.Done(): - return ctx.Err() - case <-timer.C: - return nil - } -} - func defaultJitter(max time.Duration) time.Duration { if max <= 0 { return 0 diff --git a/pkg/utils/llm_retry_test.go b/pkg/utils/llm_retry_test.go index d3175e98a..c51729598 100644 --- a/pkg/utils/llm_retry_test.go +++ b/pkg/utils/llm_retry_test.go @@ -150,3 +150,16 @@ func TestLLMRetry_DoWithRetry_UsesRetryAfterFor429(t *testing.T) { t.Fatalf("slept = %v, want 3s", slept) } } + +func TestLLMRetry_ExtractRetryAfter_HTTPDate(t *testing.T) { + now := time.Date(2015, 10, 21, 7, 27, 0, 0, time.UTC) + err := errors.New("API request failed:\n Status: 429\n Retry-After: Wed, 21 Oct 2015 07:28:00 GMT") + + delay, ok := extractRetryAfter(err, now) + if !ok { + t.Fatal("expected retry-after date to parse") + } + if delay != time.Minute { + t.Fatalf("delay = %v, want 1m", delay) + } +}