{"record":{"id":"da0a4039f440515a","repo":"jackwener/OpenCLI","slug":"zsxq-whoami-failed-probe-detail","errorCode":null,"errorMessage":"zsxq whoami failed: ${probe.detail}","messagePattern":"zsxq whoami failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zsxq/auth.js","lineNumber":38,"sourceCode":"        });\n        if (r.status === 401 || r.status === 403) {\n          return { kind: 'auth', detail: 'zsxq /v2/users/self returned HTTP ' + r.status };\n        }\n        if (!r.ok) return { kind: 'http', httpStatus: r.status };\n        const d = await r.json();\n        if (d?.succeeded === false || !d?.resp_data?.user) {\n          return { kind: 'auth', detail: 'zsxq /v2/users/self returned succeeded=false — anonymous' };\n        }\n        const u = d.resp_data.user;\n        return { ok: true, user_id: String(u.user_id || u.id || ''), name: String(u.name || u.nickname || '') };\n      } catch (e) {\n        return { kind: 'exception', detail: String(e && e.message || e) };\n      }\n    })()\n  `);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('zsxq.com', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from zsxq /v2/users/self`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`zsxq whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected zsxq probe: ${JSON.stringify(probe)}`);\n  if (!probe.user_id) {\n    throw new AuthRequiredError('zsxq.com', 'zsxq /v2/users/self 200 but user_id missing — incomplete session');\n  }\n  return { user_id: probe.user_id, name: probe.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'zsxq',\n  domain: 'zsxq.com',\n  loginUrl: 'https://wx.zsxq.com/login',\n  columns: ['user_id', 'name'],\n  verify: verifyZsxqIdentity,\n  // No-navigation poll: probe the API from the current page so the login-page\n  // QR code isn't reset by a goto on every interval.\n  poll: async (page) => {\n    const loggedIn = await page.evaluate(`(async () => {\n      try {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zsxq/auth.js#L20-L56","documentation":"The probe wraps its fetch logic in a try/catch inside the page; any exception thrown there (network failure, JSON parse error, runtime error) is returned as kind:'exception' and re-thrown as CommandExecutionError with the inner message. It means the whoami check itself crashed rather than returning an HTTP status.","triggerScenarios":"fetch() to /v2/users/self throws (DNS failure, connection refused, CORS/network error), or r.json() fails on a non-JSON response (e.g. an HTML login page or proxy error page).","commonSituations":"No network connectivity; corporate proxy returning HTML error pages; zsxq serving an HTML redirect instead of JSON; page navigation destroying the execution context mid-probe.","solutions":["Read probe.detail in the message to identify the underlying exception (TypeError: fetch failed, JSON parse error, etc.).","Verify network connectivity and DNS resolution for api.zsxq.com from the machine running the browser.","Check whether the response is HTML instead of JSON — usually a redirect to a login page; establish a logged-in session first.","Re-run the probe after ensuring the page is on a zsxq.com origin so the fetch carries proper cookies."],"exampleFix":"// before\nconst who = await verifyZsxqIdentity(page);\n// after\ntry {\n  const who = await verifyZsxqIdentity(page);\n} catch (e) {\n  if (e.message.startsWith('zsxq whoami failed')) {\n    console.error('probe detail:', e.message);\n    await page.goto('https://zsxq.com', { waitUntil: 'domcontentloaded' });\n    return verifyZsxqIdentity(page);\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// preflight: confirm api.zsxq.com is reachable from the browser context\nawait page.goto('https://api.zsxq.com', { waitUntil: 'domcontentloaded', timeout: 15000 });","typeGuard":"const isWhoamiFailure = (e) => (e?.message || '').startsWith('zsxq whoami failed:');","tryCatchPattern":"try {\n  return await verifyZsxqIdentity(page);\n} catch (e) {\n  if (isWhoamiFailure(e)) {\n    console.error('probe exception:', e.message);\n    await page.goto('https://zsxq.com', { waitUntil: 'domcontentloaded' });\n    return verifyZsxqIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Ensure stable network/DNS for api.zsxq.com before starting automation.","Keep the page on a zsxq.com origin so fetches carry cookies and avoid redirects to HTML.","Avoid navigating the page while the probe is executing."],"tags":["network","fetch","json"],"backgroundTag":"fetch-network-failure","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}