From b84068f1734a74716750b8ade4ed7e5c2c4fa6b8 Mon Sep 17 00:00:00 2001 From: Jeremias Menichelli Date: Wed, 25 Mar 2026 11:08:56 +0100 Subject: [PATCH] fix(Docs): Apply retry strategy, improve error throwing (#44173) --- .../database/database-advisors/page.tsx | 3 +- .../ai-skills/AiSkills.utils.ts | 3 +- apps/docs/lib/octokit.ts | 23 ++- apps/docs/package.json | 3 +- pnpm-lock.yaml | 142 +++++++++++++++++- 5 files changed, 158 insertions(+), 16 deletions(-) diff --git a/apps/docs/app/guides/database/database-advisors/page.tsx b/apps/docs/app/guides/database/database-advisors/page.tsx index 630c7c3ee59..334be03cd77 100644 --- a/apps/docs/app/guides/database/database-advisors/page.tsx +++ b/apps/docs/app/guides/database/database-advisors/page.tsx @@ -6,7 +6,7 @@ import { Admonition } from 'ui-patterns' import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template' import { genGuideMeta } from '~/features/docs/GuidesMdx.utils' import { MDXRemoteBase } from '~/features/docs/MdxBase' -import { getGitHubFileContents, octokit } from '~/lib/octokit' +import { OCTOKIT_RETRY_OPTIONS, getGitHubFileContents, octokit } from '~/lib/octokit' import { TabPanel, Tabs } from '~/features/ui/Tabs' import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform' import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition' @@ -151,6 +151,7 @@ const getLints = async () => { headers: { 'X-GitHub-Api-Version': '2022-11-28', }, + request: OCTOKIT_RETRY_OPTIONS, }) if (response.status >= 400) { diff --git a/apps/docs/app/guides/getting-started/ai-skills/AiSkills.utils.ts b/apps/docs/app/guides/getting-started/ai-skills/AiSkills.utils.ts index ca7f7ff1b67..b6b68853082 100644 --- a/apps/docs/app/guides/getting-started/ai-skills/AiSkills.utils.ts +++ b/apps/docs/app/guides/getting-started/ai-skills/AiSkills.utils.ts @@ -1,7 +1,7 @@ import matter from 'gray-matter' import { cache } from 'react' -import { getGitHubFileContents, octokit } from '~/lib/octokit' +import { OCTOKIT_RETRY_OPTIONS, getGitHubFileContents, octokit } from '~/lib/octokit' const SKILLS_REPO = { org: 'supabase', @@ -28,6 +28,7 @@ async function getAiSkillsImpl(): Promise { repo: SKILLS_REPO.repo, path: SKILLS_REPO.path, ref: SKILLS_REPO.branch, + request: OCTOKIT_RETRY_OPTIONS, }) if (!Array.isArray(contents)) { diff --git a/apps/docs/lib/octokit.ts b/apps/docs/lib/octokit.ts index 4cf5499566c..a957cca87cc 100644 --- a/apps/docs/lib/octokit.ts +++ b/apps/docs/lib/octokit.ts @@ -2,11 +2,19 @@ import 'server-only' import { createAppAuth } from '@octokit/auth-app' import { Octokit } from '@octokit/core' +import { retry } from '@octokit/plugin-retry' import crypto from 'node:crypto' import { fetchRevalidatePerDay } from '~/features/helpers.fetch' -let octokitInstance: Octokit +const RetryOctokit = Octokit.plugin(retry) + +export const OCTOKIT_RETRY_OPTIONS = { + retries: 5, + retryAfter: 1, +} as const + +let octokitInstance: InstanceType export function octokit() { if (!octokitInstance) { @@ -21,7 +29,7 @@ export function octokit() { format: 'pem', }) - octokitInstance = new Octokit({ + octokitInstance = new RetryOctokit({ authStrategy: createAppAuth, auth: { appId: process.env.DOCS_GITHUB_APP_ID, @@ -72,6 +80,7 @@ export async function getGitHubFileContents({ repo: repo, path: path, ref: branch, + request: OCTOKIT_RETRY_OPTIONS, options: { fetch: fetch ?? fetchRevalidatePerDay, }, @@ -81,26 +90,23 @@ export async function getGitHubFileContents({ `getGitHubFileContents: request failed for ${org}/${repo}/${path}@${branch}`, { cause: err } ) - console.error(error) onError?.(error) - return '' + throw error } if (Array.isArray(response.data)) { const error = new Error( `getGitHubFileContents: ${path} in ${org}/${repo} is a directory, not a file` ) - console.error(error) onError?.(error) - return '' + throw error } if (!('content' in response.data) || response.data.type !== 'file') { const error = new Error( `getGitHubFileContents: unexpected response for ${path} in ${org}/${repo} (type: ${'type' in response.data ? response.data.type : 'unknown'})` ) - console.error(error) onError?.(error) - return '' + throw error } return Buffer.from(response.data.content, 'base64').toString('utf-8') @@ -157,6 +163,7 @@ async function checkForImmutableCommit({ headers: { 'X-GitHub-Api-Version': '2022-11-28', }, + request: OCTOKIT_RETRY_OPTIONS, options: { fetch: _fetch, }, diff --git a/apps/docs/package.json b/apps/docs/package.json index 1f562c8413e..63f5a95d24a 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -49,9 +49,10 @@ "@next/bundle-analyzer": "15.3.1", "@next/mdx": "15.3.1", "@octokit/auth-app": "^7.0.0", - "@octokit/core": "^6.0.0", + "@octokit/core": "^7.0.6", "@octokit/graphql": "^8.0.0", "@octokit/plugin-paginate-graphql": "^4.0.0", + "@octokit/plugin-retry": "^8.1.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-collapsible": "^1.0.3", "@sentry/nextjs": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32c55f463d7..3c7d535fb46 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -314,14 +314,17 @@ importers: specifier: ^7.0.0 version: 7.1.5 '@octokit/core': - specifier: ^6.0.0 - version: 6.1.4 + specifier: ^7.0.6 + version: 7.0.6 '@octokit/graphql': specifier: ^8.0.0 version: 8.2.1 '@octokit/plugin-paginate-graphql': specifier: ^4.0.0 - version: 4.0.0(@octokit/core@6.1.4) + version: 4.0.0(@octokit/core@7.0.6) + '@octokit/plugin-retry': + specifier: ^8.1.0 + version: 8.1.0(@octokit/core@7.0.6) '@radix-ui/react-accordion': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -5066,18 +5069,34 @@ packages: resolution: {integrity: sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==} engines: {node: '>= 18'} + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} + '@octokit/core@6.1.4': resolution: {integrity: sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==} engines: {node: '>= 18'} + '@octokit/core@7.0.6': + resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} + engines: {node: '>= 20'} + '@octokit/endpoint@10.1.3': resolution: {integrity: sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==} engines: {node: '>= 18'} + '@octokit/endpoint@11.0.3': + resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} + engines: {node: '>= 20'} + '@octokit/graphql@8.2.1': resolution: {integrity: sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==} engines: {node: '>= 18'} + '@octokit/graphql@9.0.3': + resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} + engines: {node: '>= 20'} + '@octokit/oauth-authorization-url@7.1.1': resolution: {integrity: sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==} engines: {node: '>= 18'} @@ -5089,6 +5108,12 @@ packages: '@octokit/openapi-types@23.0.1': resolution: {integrity: sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==} + '@octokit/openapi-types@25.1.0': + resolution: {integrity: sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==} + + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} + '@octokit/plugin-paginate-graphql@4.0.0': resolution: {integrity: sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==} engines: {node: '>= 18'} @@ -5113,10 +5138,28 @@ packages: peerDependencies: '@octokit/core': '>=6' + '@octokit/plugin-retry@8.1.0': + resolution: {integrity: sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=7' + '@octokit/request-error@6.1.7': resolution: {integrity: sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==} engines: {node: '>= 18'} + '@octokit/request-error@6.1.8': + resolution: {integrity: sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ==} + engines: {node: '>= 18'} + + '@octokit/request-error@7.1.0': + resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.8': + resolution: {integrity: sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==} + engines: {node: '>= 20'} + '@octokit/request@9.2.2': resolution: {integrity: sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==} engines: {node: '>= 18'} @@ -5128,6 +5171,12 @@ packages: '@octokit/types@13.8.0': resolution: {integrity: sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==} + '@octokit/types@14.1.0': + resolution: {integrity: sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==} + + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + '@oozcitak/dom@2.0.2': resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==} engines: {node: '>=20.0'} @@ -9942,6 +9991,9 @@ packages: before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + better-ajv-errors@1.2.0: resolution: {integrity: sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==} engines: {node: '>= 12.13.0'} @@ -9992,6 +10044,9 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} @@ -11899,6 +11954,9 @@ packages: fast-content-type-parse@2.0.1: resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} + fast-content-type-parse@3.0.0: + resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -13457,6 +13515,9 @@ packages: resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} engines: {node: '>= 0.2.0'} + json-with-bigint@3.5.7: + resolution: {integrity: sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -22173,6 +22234,8 @@ snapshots: '@octokit/auth-token@5.1.2': {} + '@octokit/auth-token@6.0.0': {} + '@octokit/core@6.1.4': dependencies: '@octokit/auth-token': 5.1.2 @@ -22183,32 +22246,61 @@ snapshots: before-after-hook: 3.0.2 universal-user-agent: 7.0.2 + '@octokit/core@7.0.6': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.3 + '@octokit/request': 10.0.8 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.2 + '@octokit/endpoint@10.1.3': dependencies: '@octokit/types': 13.8.0 universal-user-agent: 7.0.2 + '@octokit/endpoint@11.0.3': + dependencies: + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.2 + '@octokit/graphql@8.2.1': dependencies: '@octokit/request': 9.2.2 '@octokit/types': 13.8.0 universal-user-agent: 7.0.2 + '@octokit/graphql@9.0.3': + dependencies: + '@octokit/request': 10.0.8 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.2 + '@octokit/oauth-authorization-url@7.1.1': {} '@octokit/oauth-methods@5.1.4': dependencies: '@octokit/oauth-authorization-url': 7.1.1 '@octokit/request': 9.2.2 - '@octokit/request-error': 6.1.7 + '@octokit/request-error': 6.1.8 '@octokit/types': 13.8.0 '@octokit/openapi-types@23.0.1': {} + '@octokit/openapi-types@25.1.0': {} + + '@octokit/openapi-types@27.0.0': {} + '@octokit/plugin-paginate-graphql@4.0.0(@octokit/core@6.1.4)': dependencies: '@octokit/core': 6.1.4 + '@octokit/plugin-paginate-graphql@4.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/plugin-paginate-rest@11.4.3(@octokit/core@6.1.4)': dependencies: '@octokit/core': 6.1.4 @@ -22223,14 +22315,38 @@ snapshots: '@octokit/core': 6.1.4 '@octokit/types': 13.8.0 + '@octokit/plugin-retry@8.1.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + '@octokit/request-error@6.1.7': dependencies: '@octokit/types': 13.8.0 + '@octokit/request-error@6.1.8': + dependencies: + '@octokit/types': 14.1.0 + + '@octokit/request-error@7.1.0': + dependencies: + '@octokit/types': 16.0.0 + + '@octokit/request@10.0.8': + dependencies: + '@octokit/endpoint': 11.0.3 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + fast-content-type-parse: 3.0.0 + json-with-bigint: 3.5.7 + universal-user-agent: 7.0.2 + '@octokit/request@9.2.2': dependencies: '@octokit/endpoint': 10.1.3 - '@octokit/request-error': 6.1.7 + '@octokit/request-error': 6.1.8 '@octokit/types': 13.8.0 fast-content-type-parse: 2.0.1 universal-user-agent: 7.0.2 @@ -22246,6 +22362,14 @@ snapshots: dependencies: '@octokit/openapi-types': 23.0.1 + '@octokit/types@14.1.0': + dependencies: + '@octokit/openapi-types': 25.1.0 + + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + '@oozcitak/dom@2.0.2': dependencies: '@oozcitak/infra': 2.0.2 @@ -27662,6 +27786,8 @@ snapshots: before-after-hook@3.0.2: {} + before-after-hook@4.0.0: {} + better-ajv-errors@1.2.0(ajv@8.18.0): dependencies: '@babel/code-frame': 7.29.0 @@ -27738,6 +27864,8 @@ snapshots: boolbase@1.0.0: {} + bottleneck@2.19.5: {} + bowser@2.11.0: {} boxen@8.0.1: @@ -29894,6 +30022,8 @@ snapshots: fast-content-type-parse@2.0.1: {} + fast-content-type-parse@3.0.0: {} + fast-deep-equal@3.1.3: {} fast-equals@4.0.3: {} @@ -31570,6 +31700,8 @@ snapshots: remedial: 1.0.8 remove-trailing-spaces: 1.0.9 + json-with-bigint@3.5.7: {} + json5@1.0.2: dependencies: minimist: 1.2.8