{"record":{"id":"cb6f9aa88251c3b6","repo":"jackwener/OpenCLI","slug":"http-probe-httpstatus-from-gitee-api-v5-user","errorCode":null,"errorMessage":"HTTP ${probe.httpStatus} from Gitee /api/v5/user","messagePattern":"HTTP (.+?) from Gitee /api/v5/user","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gitee/auth.js","lineNumber":24,"sourceCode":"const WHOAMI_PROBE = `(async () => {\n  try {\n    const r = await fetch('/api/v5/user', { credentials: 'include', headers: { Accept: 'application/json' } });\n    if (r.status === 401 || r.status === 403) return { kind: 'auth', detail: 'Gitee /api/v5/user HTTP ' + r.status };\n    if (!r.ok) return { kind: 'http', httpStatus: r.status };\n    const d = await r.json();\n    if (!d || !d.id || !d.login) return { kind: 'auth', detail: 'Gitee /api/v5/user has no id/login — anonymous' };\n    return { ok: true, user_id: String(d.id), username: String(d.login), name: String(d.name || '') };\n  } catch (e) {\n    return { kind: 'exception', detail: String(e && e.message || e) };\n  }\n})()`;\n\nasync function verifyGiteeIdentity(page) {\n  await page.goto('https://gitee.com/');\n  await page.wait(1);\n  const probe = await page.evaluate(WHOAMI_PROBE);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('gitee.com', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from Gitee /api/v5/user`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`Gitee whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Gitee probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, username: probe.username, name: probe.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'gitee',\n  domain: 'gitee.com',\n  loginUrl: 'https://gitee.com/login',\n  columns: ['user_id', 'username', 'name'],\n  verify: verifyGiteeIdentity,\n  poll: async (page) => {\n    const probe = await page.evaluate(WHOAMI_PROBE);\n    if (!probe?.ok) throw new AuthRequiredError('gitee.com', 'Waiting for Gitee login');\n    return { user_id: probe.user_id, username: probe.username, name: probe.name };\n  },\n});\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gitee/auth.js#L6-L42","documentation":"In verifyGiteeIdentity (clis/gitee/auth.js), when the in-page fetch to https://gitee.com/api/v5/user responds with any non-OK status other than 401/403, the probe yields kind 'http' and this CommandExecutionError is thrown with the actual HTTP status. It means the Gitee API itself rejected the request at the HTTP level rather than reporting an auth problem.","triggerScenarios":"The WHOAMI_PROBE fetch receives a status like 429 (rate limited), 5xx (Gitee server error), 404 (API path changed), or a proxy/WAF block page status while verifying the Gitee identity.","commonSituations":"Gitee rate limiting after many rapid probes (429); transient Gitee server incidents (5xx); corporate proxy or WAF intercepting requests; Gitee API path/version change breaking /api/v5/user.","solutions":["Read the HTTP status in the message and retry after backoff if it is 429 or 5xx.","Open https://gitee.com/api/v5/user in a normal browser to see the raw response and confirm the API path still works.","Check for a proxy/firewall intercepting the automated browser's requests.","Check Gitee status/announcements for an outage or API change; update the probe URL if the API version changed."],"exampleFix":"// before — failing hard on transient HTTP errors\nconst identity = await verifyGiteeIdentity(page);\n// after — retry on retryable statuses\nlet identity;\nfor (let i = 0; i < 3; i++) {\n  try { identity = await verifyGiteeIdentity(page); break; }\n  catch (e) {\n    if (!/HTTP (429|5\\d\\d)/.test(e.message) || i === 2) throw e;\n    await new Promise(r => setTimeout(r, 2 ** i * 1000));\n  }\n}","handlingStrategy":"retry","validationCode":"const res = await fetch('https://gitee.com/api/v5/user');\nif (!res.ok) console.warn('Gitee API currently answering HTTP', res.status);","typeGuard":"function isRetryableHttp(msg) { return /HTTP (429|5\\d\\d) /.test(msg); }","tryCatchPattern":"try {\n  const identity = await verifyGiteeIdentity(page);\n} catch (err) {\n  const m = err.message.match(/HTTP (\\d{3})/);\n  if (m && (m[1] === '429' || m[1].startsWith('5'))) {\n    await sleep(2000); // then retry with backoff\n  } else throw err;\n}","preventionTips":["Throttle repeated probes to avoid Gitee rate limiting (429).","Wrap identity verification in exponential-backoff retry for 429/5xx only.","Monitor Gitee status for API outages or endpoint changes.","Check proxy/WAF configuration for the automated browser."],"tags":["gitee","http","api-error","network"],"backgroundTag":"http-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}