{"record":{"id":"e026c48aac7742ae","repo":"jackwener/OpenCLI","slug":"xueqiu-com-e026c4","errorCode":null,"errorMessage":"xueqiu.com","messagePattern":"xueqiu\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xueqiu/groups.js","lineNumber":16,"sourceCode":"import { cli } from '@jackwener/opencli/registry';\nimport { AuthRequiredError } from '@jackwener/opencli/errors';\nimport { fetchXueqiuJson } from './utils.js';\ncli({\n    site: 'xueqiu',\n    name: 'groups',\n    access: 'read',\n    description: '获取雪球自选股分组列表（含模拟组合）',\n    domain: 'xueqiu.com',\n    browser: true,\n    columns: ['pid', 'name', 'count'],\n    func: async (page, _kwargs) => {\n        await page.goto('https://xueqiu.com');\n        const d = await fetchXueqiuJson(page, 'https://stock.xueqiu.com/v5/stock/portfolio/list.json?category=1&size=20');\n        if (!d.data?.stocks)\n            throw new AuthRequiredError('xueqiu.com');\n        return (d.data.stocks || []).map((g) => ({\n            pid: String(g.id),\n            name: g.name,\n            count: g.symbol_count || 0,\n        }));\n    },\n});\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xueqiu/groups.js#L1-L24","documentation":"The xueqiu groups command fetches the user's stock portfolio list from stock.xueqiu.com/v5/stock/portfolio/list.json after visiting xueqiu.com to obtain cookies. If the API response has no data.stocks, the session is not authenticated (or the API returned an error payload), so it throws AuthRequiredError('xueqiu.com') telling the user to log in. This error is thrown deliberately to signal that xueqiu requires a valid logged-in session for portfolio data.","triggerScenarios":"Calling the groups command when the browser session for xueqiu.com has no valid login cookies (expired session, first run without authentication, cookies cleared), or when xueqiu returns a non-authenticated error body (e.g. error_code for not logged in) so d.data?.stocks is undefined.","commonSituations":"Xueqiu session cookies expired (they are short-lived); user never logged into xueqiu in the shared browser profile; xueqiu rate-limited or logged the session out; running headless without restoring a logged-in profile.","solutions":["Log in to xueqiu.com in the browser session/profile the CLI uses, then re-run the groups command","Restore a saved logged-in cookie/session profile if your tooling supports it","Check the raw API response (fetchXueqiuJson) for xueqiu error codes like 400016 (not logged in) to confirm auth is the cause","Retry after some time if xueqiu is rate-limiting, since repeated unauthenticated hits can worsen it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const d = await fetchXueqiuJson(page, 'https://stock.xueqiu.com/v5/stock/portfolio/list.json?category=1&size=20');\nif (!d || d.error_code || !d.data?.stocks) {\n  throw new Error('Xueqiu session not authenticated (error_code=' + (d && d.error_description || 'none') + ') — log in to xueqiu.com first.');\n}","typeGuard":"function hasPortfolios(d) {\n  return Boolean(d && typeof d === 'object' && d.data && Array.isArray(d.data.stocks));\n}","tryCatchPattern":"try {\n  const groups = await xueqiuGroups();\n} catch (e) {\n  if (e instanceof AuthRequiredError || /AuthRequiredError|xueqiu\\.com/.test(e.message)) {\n    console.error('Please log in to xueqiu.com in the CLI browser session and retry.');\n  } else throw e;\n}","preventionTips":["Keep a persistent, logged-in xueqiu browser profile for the CLI","Periodically refresh the xueqiu session before long batch runs","Check for xueqiu error_code 400016 (not logged in) in raw responses","Avoid hammering the API, which can invalidate sessions or trigger anti-bot logout"],"tags":["auth","scraping","xueqiu","session-expired"],"backgroundTag":"auth-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}