classifyGHAPIError converts a gh API exit error into a user-friendly, pre-formatted error.
(exitCode int, stderr string, prNumber string, repo string)
| 217 | |
| 218 | // classifyGHAPIError converts a gh API exit error into a user-friendly, pre-formatted error. |
| 219 | func classifyGHAPIError(exitCode int, stderr string, prNumber string, repo string) error { |
| 220 | checksLog.Printf("API error: exitCode=%d, stderr=%s", exitCode, stderr) |
| 221 | |
| 222 | lower := strings.ToLower(stderr) |
| 223 | |
| 224 | switch { |
| 225 | case strings.Contains(lower, "404") || strings.Contains(lower, "not found"): |
| 226 | repoHint := "the current repository" |
| 227 | if repo != "" { |
| 228 | repoHint = repo |
| 229 | } |
| 230 | return errors.New(console.FormatErrorWithSuggestions( |
| 231 | fmt.Sprintf("PR #%s not found in %s", prNumber, repoHint), |
| 232 | []string{ |
| 233 | "Verify that the pull request number is correct", |
| 234 | "Use --repo owner/repo to specify the target repository explicitly", |
| 235 | "Ensure you have read access to the repository", |
| 236 | }, |
| 237 | )) |
| 238 | case strings.Contains(lower, "403") || strings.Contains(lower, "forbidden") || |
| 239 | strings.Contains(lower, "bad credentials") || strings.Contains(lower, "401") || |
| 240 | strings.Contains(lower, "unauthorized"): |
| 241 | return errors.New(console.FormatErrorWithSuggestions( |
| 242 | "GitHub API authentication failed", |
| 243 | []string{ |
| 244 | "Run 'gh auth login' to authenticate with GitHub", |
| 245 | "Ensure your token has the 'repo' scope for private repositories", |
| 246 | "Check that GH_TOKEN or GITHUB_TOKEN is set correctly if using environment variables", |
| 247 | }, |
| 248 | )) |
| 249 | default: |
| 250 | return fmt.Errorf("gh api call failed (exit %d): %s", exitCode, stderr) |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | // checkRunsAPIResponse is the envelope returned by the check-runs endpoint. |
| 255 | type checkRunsAPIResponse struct { |