{"record":{"id":"d9f963c697dc8c4d","repo":"jackwener/OpenCLI","slug":"xueqiu-com-d9f963","errorCode":null,"errorMessage":"xueqiu.com","messagePattern":"xueqiu\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xueqiu/comments.js","lineNumber":45,"sourceCode":"function toFiniteCount(value) {\n    const count = Number(value ?? 0);\n    return Number.isFinite(count) ? count : 0;\n}\nfunction normalizeIdentifier(value) {\n    if (typeof value === 'string')\n        return value.trim();\n    if (typeof value === 'number' && Number.isFinite(value))\n        return String(value);\n    return '';\n}\nfunction buildPaginationStopMessage(requestNumber, collected, target, reason) {\n    return `xueqiu comments pagination stopped after request ${requestNumber}, `\n        + `collected ${collected}/${target} items, `\n        + `reason: ${reason}`;\n}\nfunction throwFirstPageFailure(kind, symbol) {\n    if (kind === 'auth' || kind === 'anti-bot') {\n        throw new AuthRequiredError('xueqiu.com', 'Stock discussions require login or challenge clearance');\n    }\n    if (kind === 'argument') {\n        throw new ArgumentError(`xueqiu comments received an invalid symbol: ${symbol}`);\n    }\n    if (kind === 'empty') {\n        throw new EmptyResultError(`xueqiu/comments ${symbol}`, `No discussion data found for ${symbol}`);\n    }\n    throw new CommandExecutionError(`Unexpected response while loading xueqiu comments for ${symbol}`, 'Run the command again with --verbose to inspect the raw site response.');\n}\n/**\n * Extract the raw item list from one classified JSON payload.\n *\n * @param json Raw parsed JSON payload from browser fetch.\n * @returns Discussion items when the response shape is usable.\n */\nexport function getCommentItems(json) {\n    if (!isRecord(json))\n        return [];","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xueqiu/comments.js#L27-L63","documentation":"throwFirstPageFailure maps the classification of the first comments response to a typed error. When the first page is classified as 'auth' (HTTP 401/403 or login-required text) or 'anti-bot' (captcha/WAF HTML), collectCommentRows throws AuthRequiredError('xueqiu.com', 'Stock discussions require login or challenge clearance'). Xueqiu requires a logged-in, challenge-cleared session to read stock discussions.","triggerScenarios":"First request to https://xueqiu.com/query/v1/symbol/search/status returns 401/403, or returns text/html containing captcha/challenge/aliyun_waf markers, while running `opencli xueqiu comments <symbol>` with an anonymous or WAF-challenged session.","commonSituations":"Running without ever completing `xueqiu auth login`; xq_a_token cookie expired; xueqiu's Aliyun WAF issued a captcha after heavy scraping; running from a datacenter IP that gets challenged.","solutions":["Run the xueqiu auth login command and complete login in the opened browser to obtain xq_a_token","If recently logged in, visit https://xueqiu.com/ manually and solve any captcha/WAF challenge, then retry","Slow down request rate or wait if you suspect rate limiting triggered the anti-bot page","Retry from a residential/different network if datacenter IP challenges persist"],"exampleFix":"// before (calling comments while anonymous)\nawait collectCommentRows({ symbol: 'SH600519', ... });\n// after (guard on quickCheck first)\nif (!await hasXueqiuAccessToken(page)) {\n  throw new AuthRequiredError('xueqiu.com', 'Login first: opencli xueqiu auth login');\n}\nawait collectCommentRows({ symbol: 'SH600519', ... });","handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://xueqiu.com' });\nif (!cookies.some(c => c.name === 'xq_a_token' && c.value)) {\n  throw new Error('Run `opencli xueqiu auth login` before fetching comments');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const rows = await collectCommentRows(opts);\n} catch (e) {\n  if (e.name === 'AuthRequiredError') {\n    console.error('Login to xueqiu (and clear any captcha) before fetching comments');\n  } else throw e;\n}","preventionTips":["Run `xueqiu auth login` and verify before any comments fetch","Throttle request rates to avoid triggering the Aliyun WAF","Solve captchas in the automation browser promptly when they appear","Re-login when sessions age out rather than retrying anonymously"],"tags":["auth","anti-bot","xueqiu","login-required"],"backgroundTag":"auth-required-login-first","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}