mirror of
https://github.com/lukaszraczylo/git-velocity.git
synced 2026-06-18 03:43:56 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09b0c533b4 |
@@ -301,12 +301,16 @@ func isRetryableError(err error) bool {
|
|||||||
"timeout",
|
"timeout",
|
||||||
"temporary failure",
|
"temporary failure",
|
||||||
"server error",
|
"server error",
|
||||||
|
"stream error",
|
||||||
|
"CANCEL",
|
||||||
|
"EOF",
|
||||||
|
"broken pipe",
|
||||||
"502",
|
"502",
|
||||||
"503",
|
"503",
|
||||||
"504",
|
"504",
|
||||||
}
|
}
|
||||||
for _, msg := range retryableMessages {
|
for _, msg := range retryableMessages {
|
||||||
if strings.Contains(strings.ToLower(errStr), msg) {
|
if strings.Contains(strings.ToLower(errStr), strings.ToLower(msg)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/progress"
|
"github.com/charmbracelet/bubbles/progress"
|
||||||
@@ -133,8 +134,28 @@ func fetchGQLPaginated[Q any, T any, R any](
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if err := client.Query(ctx, config.Query, variables); err != nil {
|
// Retry logic for transient errors
|
||||||
return nil, fmt.Errorf("graphql query failed: %w", err)
|
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<<retries) * time.Second
|
||||||
|
fmt.Fprintf(os.Stderr, "\r GraphQL retry %d/3 (waiting %s): %v\n", retries+1, backoff, queryErr)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case <-time.After(backoff):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if queryErr != nil {
|
||||||
|
return nil, fmt.Errorf("graphql query failed: %w", queryErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
page := config.GetPageResult(config.Query)
|
page := config.GetPageResult(config.Query)
|
||||||
@@ -520,3 +541,33 @@ func convertCommentNode(node gqlCommentNode, repoName string, issueNumber int) m
|
|||||||
CreatedAt: node.CreatedAt,
|
CreatedAt: node.CreatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isGQLRetryableError checks if a GraphQL error is transient and should be retried
|
||||||
|
func isGQLRetryableError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
errStr := strings.ToLower(err.Error())
|
||||||
|
retryablePatterns := []string{
|
||||||
|
"stream error",
|
||||||
|
"cancel",
|
||||||
|
"eof",
|
||||||
|
"connection reset",
|
||||||
|
"connection refused",
|
||||||
|
"timeout",
|
||||||
|
"temporary failure",
|
||||||
|
"broken pipe",
|
||||||
|
"502",
|
||||||
|
"503",
|
||||||
|
"504",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pattern := range retryablePatterns {
|
||||||
|
if strings.Contains(errStr, pattern) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user