Add detailed logging for GitHub API errors - #131
Conversation
When a GitHub App returns "resource not accessible by integration" or other permission errors, the connector now logs the full GitHub error message, HTTP status code, request method, and URL. This makes it possible to identify exactly which API call is failing and why. Changes: - Add gitHubErrorMessage() helper to extract detailed error info from GitHub API responses including error sub-fields - Add logGitHubAPIError() for structured warn-level logging of all GitHub API errors with method, URL, status, and error message - Add wrapGitHubErrorWithContext() variant that logs before wrapping - Update all sync operations (List, Grants) to use context-aware error wrapping with specific resource identifiers (org name, repo name, team ID, role ID) - Enhance existing 403-skip warn logs to include the GitHub error message so silently-skipped resources are debuggable Fixes: CXH-1226
|
Claude finished @c1-dev-bot[bot]'s task in 1m 10s —— View job PR Review: Add detailed logging for GitHub API errors
Overall AssessmentThis is a solid, well-scoped PR that addresses a real debugging pain point. The approach is clean — adding a Approve with minor suggestions — see inline comments for details. What looks good
Suggestions (minor, non-blocking)
No issues found with
|
| } | ||
| } | ||
|
|
||
| l.Warn("github API error", fields...) |
There was a problem hiding this comment.
Nit: For rate-limit and temporary-unavailability errors, wrapGitHubError returns early (lines 372, 378, 383, 388) without including the GitHub error message or contextMsg. This means wrapGitHubErrorWithContext will log the error at warn level via logGitHubAPIError, but the returned error won't contain the operation context or GitHub message — only generic strings like "rate limit exceeded" or "too many requests".
This is probably acceptable since rate-limit errors are transient and retried, but it's worth noting the asymmetry: auth/permission errors get the enriched message while rate-limit errors don't.
| l.Warn("error fetching user by id", | ||
| zap.Error(err), | ||
| zap.Int64("user_id", user.GetID()), | ||
| zap.String("github_error", gitHubErrorMessage(err)), | ||
| ) |
There was a problem hiding this comment.
Minor: zap.Error(err) and zap.String("github_error", gitHubErrorMessage(err)) will produce overlapping information. The Error(err) field will contain the full github.ErrorResponse.Error() string, and gitHubErrorMessage(err) extracts a subset of it. Not a bug, but slightly redundant. Consider keeping just one — either zap.Error(err) for the full error chain or zap.String("github_error", ...) for the parsed message.
| fields := []zap.Field{ | ||
| zap.String("operation", contextMsg), | ||
| zap.String("github_error", gitHubErrorMessage(err)), | ||
| } |
There was a problem hiding this comment.
Consider also including zap.Error(err) in the fields list. Currently the log only includes the parsed github_error string, which loses the full error chain (e.g., any wrapped context from the HTTP transport layer). Adding the original error preserves the full chain for debugging:
| fields := []zap.Field{ | |
| zap.String("operation", contextMsg), | |
| zap.String("github_error", gitHubErrorMessage(err)), | |
| } | |
| fields := []zap.Field{ | |
| zap.String("operation", contextMsg), | |
| zap.Error(err), | |
| zap.String("github_error", gitHubErrorMessage(err)), | |
| } |
Graceful-skip log paths fire per-resource when a GitHub App lacks permissions, producing excessive Warn volume in Datadog. These are expected behavior for limited-scope installations, not actionable warnings. Context remains available at LOG_LEVEL=debug.
|
Claude finished @johnallers's task in 1m 22s —— View job PR Review: Add detailed logging for GitHub API errors
Overall AssessmentApprove with minor suggestions. This is a well-scoped PR that solves a real debugging pain point. The approach — adding The second commit ( What looks good
Issues to address1. Missing
|
|
Closing in favor of #132 |
Summary
When a GitHub App returns "resource not accessible by integration" or other permission/auth errors, the connector's logs didn't include enough detail to identify which specific API call was failing. This made it very difficult to debug issues for customers using GitHub Enterprise with read-only permissions.
This PR adds structured logging for all GitHub API errors so that the exact failing endpoint, HTTP status, and GitHub error message are captured in logs.
Changes
helpers.go: Added three new functions:gitHubErrorMessage()- Extracts the full error message from*github.ErrorResponseincluding sub-error details (resource, field, code)logGitHubAPIError()- Logs GitHub API errors at warn level with structured fields: operation, HTTP status, method, URL, and the GitHub error messagewrapGitHubErrorWithContext()- Combines logging + error wrapping for use in sync operations wherecontext.Contextis availablewrapGitHubError()to include the GitHub error message in permission/auth error gRPC status messagesAll resource sync files (
repository.go,org.go,team.go,user.go,org_role.go,api_token.go,invitation.go,enterprise_role.go,connector.go):wrapGitHubErrorWithContext()for context-aware logginggitHubErrorMessage(err)so that silently-skipped resources show the exact GitHub errorTest plan
go build ./...passesgo test ./...passesFixes: CXH-1226
Automated PR Notice
This PR was automatically created by c1-dev-bot as a potential implementation.
This code requires: