Skip to content

Replace custom retry() with @octokit/plugin-retry#947

Merged
qoomon merged 5 commits intomainfrom
copilot/deep-dive-server-response-issues
Mar 11, 2026
Merged

Replace custom retry() with @octokit/plugin-retry#947
qoomon merged 5 commits intomainfrom
copilot/deep-dive-server-response-issues

Conversation

Copy link
Contributor

Copilot AI commented Mar 10, 2026

  • Install @octokit/plugin-retry as a production dependency
  • Add retryPlugin to the Octokit plugin chain
  • Move retry config from Octokit constructor to per-request options
  • Replace @octokit/plugin-retry with a local octokitRetryPlugin that reads request.{ retries, retryAfter, doNotRetry } from per-request options via Octokit's hook.error API
  • Remove OCTOKIT_RETRY_OPTIONS shared constant
  • Each call site specifies its own request: { retries, retryAfter, doNotRetry } with semantically correct per-call doNotRetry lists:
    • getUserInstallationdoNotRetry: [Status.NOT_FOUND]
    • createInstallationAccessTokendoNotRetry: [Status.UNPROCESSABLE_ENTITY]
    • getContentdoNotRetry: [Status.NOT_FOUND]
  • Uninstall @octokit/plugin-retry
  • Run tests

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…etAccessPolicy

Co-authored-by: qoomon <3963394+qoomon@users.noreply.github.com>
Copilot AI changed the title [WIP] Investigate server response failures in access-token-manager and app Fix transient GitHub API connection failures causing missing or misleading server responses Mar 10, 2026
@qoomon qoomon marked this pull request as ready for review March 10, 2026 06:57
Copilot AI review requested due to automatic review settings March 10, 2026 06:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves resilience against transient GitHub API connection closures by fixing the shared retry() helper and applying consistent retry behavior to GitHub API calls involved in access-policy reads and installation token creation.

Changes:

  • Fix retry() to correctly rethrow the final error and to await async onRetry/onError callbacks.
  • Add Jest unit tests covering retry() success, failure, and callback short-circuiting behavior.
  • Add retry wrappers around access policy file reads and installation access token creation in access-token-manager.ts.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
server/test/common/common-utils.test.ts Adds unit tests validating retry boundaries and async callback behavior.
server/src/common/common-utils.ts Fixes retry() loop boundary and awaits async onRetry/onError callbacks; avoids sleeping after final attempt.
server/src/access-token-manager.ts Adds retry around access policy fetch and installation access token creation to mitigate transient GitHub API connection issues.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +609 to +615
return retry(
() => getRepositoryFileContent(client, {owner, repo, path, maxSize: ACCESS_POLICY_MAX_SIZE}),
{retries: 3, delay: 1000},
).catch((error) => {
logger.error({owner, repo, path, error: String(error)}, 'Failed to get access policy file content');
return null;
}
});
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getRepositoryFileContent() already returns null for 404 and throws for non-404 errors. This .catch(() => null) converts any remaining non-404 error (after retries) into null, which later becomes Access policy not found and hides real GitHub/API failures. Consider only mapping "not found" to null and propagating other errors (or tracking an error and throwing it if all paths fail due to non-404 errors).

Copilot uses AI. Check for mistakes.
Comment on lines 615 to 618
});
});
if (!policyValue) {
throw new GithubAccessPolicyError(`Access policy not found`);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!policyValue) treats an empty access policy file ('') the same as null/missing, which will throw Access policy not found instead of Invalid access policy. Prefer an explicit null check here (and ensure the findFirstNotNull callback doesn’t drop empty strings due to truthiness).

Copilot uses AI. Check for mistakes.
Comment on lines +956 to +960
return retry(
() => client.rest.apps.createInstallationAccessToken({
installation_id: installation.id,
// BE AWARE that an empty object will result in a token with all app installation permissions
permissions: ensureHasEntries(mapObjectEntries(permissions, ([scope, permission]) => [
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping createInstallationAccessToken in retry() without an onError predicate will retry non-transient failures (e.g., 401/403/422) as well, adding ~2s latency and extra GitHub API calls before returning the same error. Consider restricting retries to clearly transient conditions (connection resets/"line closed", 5xx, etc.) and short-circuiting on non-retryable status codes.

Copilot uses AI. Check for mistakes.
Co-authored-by: qoomon <3963394+qoomon@users.noreply.github.com>
Copilot AI changed the title Fix transient GitHub API connection failures causing missing or misleading server responses Replace custom retry() with @octokit/plugin-retry Mar 11, 2026
Copilot AI and others added 2 commits March 11, 2026 15:25
Co-authored-by: qoomon <3963394+qoomon@users.noreply.github.com>
Copilot stopped work on behalf of qoomon due to an error March 11, 2026 15:41
@qoomon qoomon merged commit f955aaf into main Mar 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants