fix(worker): classify permission sync failures by provider context#1482
Conversation
WalkthroughPermission synchronization now normalizes HTTP error metadata, classifies upstream failures by provider and operation, wraps provider API calls, and clears cached permissions only for classified credential rejection or insufficient scope failures. ChangesPermission sync classification
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant syncAccountPermissions
participant withPermissionSyncUpstreamError
participant classifyPermissionSyncUpstreamError
participant classifyPermissionSyncFailure
syncAccountPermissions->>withPermissionSyncUpstreamError: run provider scope or repository operation
withPermissionSyncUpstreamError->>classifyPermissionSyncUpstreamError: classify thrown upstream error
classifyPermissionSyncUpstreamError-->>withPermissionSyncUpstreamError: return PermissionSyncUpstreamError
withPermissionSyncUpstreamError-->>classifyPermissionSyncFailure: propagate classified failure
classifyPermissionSyncFailure-->>syncAccountPermissions: clear or preserve cached permissions
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This comment has been minimized.
This comment has been minimized.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/backend/src/ee/permissionSyncError.ts (1)
45-51: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winBroad
TypeErrormatch risks masking internal bugs as "provider unavailable".Any
TypeErrorthrown inside a wrapped callback (including unrelated coding bugs, not justfetchnetwork failures) gets classified asupstream_unavailable, producing a misleading "provider is temporarily unavailable" log/kind for what could be an internal defect. Since bothupstream_unavailableandunknowncurrently map topreserve_permissionsdownstream, there's no behavioral difference today, but it does reduce the accuracy of the errorkindfor incident triage.Consider narrowing the check to more specific network-failure signals (e.g.,
error.cause instanceof Error && error.cause.message.includes('fetch failed'), or checking forECONNRESET/ETIMEDOUTstyle codes from undici) rather than anyTypeError.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/backend/src/ee/permissionSyncError.ts` around lines 45 - 51, Narrow isNetworkOrTimeoutError so it does not classify every TypeError as an upstream outage; rely on specific network or timeout indicators such as fetch-failure causes or recognized undici connection error codes, while preserving AbortError and TimeoutError handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/backend/src/ee/permissionSyncError.ts`:
- Around line 45-51: Narrow isNetworkOrTimeoutError so it does not classify
every TypeError as an upstream outage; rely on specific network or timeout
indicators such as fetch-failure causes or recognized undici connection error
codes, while preserving AbortError and TimeoutError handling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d5d503ae-a1b0-4ab5-9c97-e73741dd87df
📒 Files selected for processing (7)
CHANGELOG.mdpackages/backend/src/ee/accountPermissionSyncer.test.tspackages/backend/src/ee/accountPermissionSyncer.tspackages/backend/src/ee/permissionSyncError.test.tspackages/backend/src/ee/permissionSyncError.tspackages/backend/src/errors.test.tspackages/backend/src/errors.ts
Replace generic HTTP status fail-closed handling with typed upstream permission-sync errors so ambiguous forbidden and gone responses preserve cached permissions. Fixes SOU-1560 Fixes SOU-1177
0954bf8 to
4d6cdd0
Compare
a985fac to
3cc17b8
Compare
Replace generic HTTP status fail-closed handling with typed upstream permission-sync errors so ambiguous forbidden and gone responses preserve cached permissions.
Fixes SOU-1560
Fixes SOU-1177
Stack created with GitHub Stacks CLI • Give Feedback 💬
Note
Medium Risk
Changes authorization-adjacent behavior: fewer cases wipe repo permissions (e.g. unclassified 403/410), which reduces accidental lockout but may briefly retain stale access if a true revocation is misclassified as unknown/forbidden.
Overview
EE account permission sync no longer clears cached repo permissions on raw HTTP 401, 403, or 410. Cleanup runs only for confirmed permanent failures: rejected OAuth refresh tokens, upstream credential rejection (classified 401 on sync calls), and missing OAuth scopes (GitHub
repo, GitLabread_api).Adds
PermissionSyncUpstreamErrorand wraps GitHub, GitLab, and Bitbucket scope checks and repo listing inwithPermissionSyncUpstreamError, which classifies failures (rate limits via status/headers, 5xx/timeouts as transient, ambiguous 403/410 as non-fatal). ExtendsgetErrorStatus/getErrorHeaderinerrors.tsso rate-limit signals work across Octokit, GitLab, and Bitbucket error shapes.Unclassified HTTP errors and kinds like
rate_limited,forbidden, andunknown(including Bitbucket Cloud 410) preserve the last successful permission snapshot.Reviewed by Cursor Bugbot for commit 3cc17b8. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit