From 09b0c533b41056fce133f64233a6af7a30efe0dd Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Fri, 12 Dec 2025 01:56:52 +0000 Subject: [PATCH] Add retry logic for GitHub graphql requests --- internal/github/client.go | 6 ++++- internal/github/graphql.go | 55 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/internal/github/client.go b/internal/github/client.go index 5d4dede..e25fd29 100644 --- a/internal/github/client.go +++ b/internal/github/client.go @@ -301,12 +301,16 @@ func isRetryableError(err error) bool { "timeout", "temporary failure", "server error", + "stream error", + "CANCEL", + "EOF", + "broken pipe", "502", "503", "504", } for _, msg := range retryableMessages { - if strings.Contains(strings.ToLower(errStr), msg) { + if strings.Contains(strings.ToLower(errStr), strings.ToLower(msg)) { return true } } diff --git a/internal/github/graphql.go b/internal/github/graphql.go index 5f6a3cd..d8b8a05 100644 --- a/internal/github/graphql.go +++ b/internal/github/graphql.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "os" + "strings" "time" "github.com/charmbracelet/bubbles/progress" @@ -133,8 +134,28 @@ func fetchGQLPaginated[Q any, T any, R any]( } for { - if err := client.Query(ctx, config.Query, variables); err != nil { - return nil, fmt.Errorf("graphql query failed: %w", err) + // Retry logic for transient errors + var queryErr error + for retries := 0; retries < 3; retries++ { + queryErr = client.Query(ctx, config.Query, variables) + if queryErr == nil { + break + } + // Check if error is retryable + if !isGQLRetryableError(queryErr) { + break + } + // Wait before retry with exponential backoff + backoff := time.Duration(1<