{"record":{"id":"d09c21478694c2e1","repo":"DIYgod/RSSHub","slug":"error-occurred-please-refresh-the-page-or-try-aga","errorCode":null,"errorMessage":"Error occurred, please refresh the page or try again after logging back into your account","messagePattern":"Error occurred, please refresh the page or try again after logging back into your account","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/xueqiu/column.ts","lineNumber":60,"sourceCode":"\n    const pageData = await got(pageUrl, {\n        cookieJar,\n    });\n    const { window } = new JSDOM(pageData.data, {\n        runScripts: 'dangerously',\n    });\n    const SNOWMAN_TARGET = window.SNOWMAN_TARGET;\n\n    const { data } = await got(`${baseUrl}/statuses/original/timeline.json`, {\n        cookieJar,\n        searchParams: {\n            user_id: id,\n            page: 1,\n        },\n    });\n\n    if (!data.list) {\n        throw new Error('Error occurred, please refresh the page or try again after logging back into your account');\n    }\n\n    const items = data.list.map((item) => ({\n        title: item.title,\n        description: item.description,\n        pubDate: parseDate(item.created_at, 'x'),\n        link: `${baseUrl}${item.target}`,\n        author: SNOWMAN_TARGET.screen_name,\n    }));\n\n    return {\n        title: `${SNOWMAN_TARGET.screen_name} - 雪球`,\n        link: pageUrl,\n        description: SNOWMAN_TARGET.description,\n        item: items,\n    };\n}\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/xueqiu/column.ts#L42-L78","documentation":"Plain Error thrown by the Xueqiu column handler after calling GET /statuses/original/timeline.json. The handler obtained an anonymous cookie via a cookieJar GET to the homepage and parsed SNOWMAN_TARGET from the column page, but the timeline API returned an object whose list field is falsy — Xueqiu's anti-crawler rejected the anonymous session. The message instructs the user to refresh or log in.","triggerScenarios":"got(baseUrl) seeds the cookieJar, got(pageUrl) loads the column HTML and runs JSDOM to extract SNOWMAN_TARGET, then got('/statuses/original/timeline.json') returns successfully (HTTP 200) but with a body like {error_description, error_code} or {list: null} because Xueqiu flagged the request as a bot. The !data.list guard then fires.","commonSituations":"Self-hosted RSSHub hitting Xueqiu from a datacenter IP that Xueqiu rate-limits; the anonymous token (xq_a_token) expired between requests; Xueqiu changed its anti-bot to require a logged-in cookie for column timelines; high request frequency tripped throttling.","solutions":["Retry after a short cooldown — Xueqiu anti-crawler is often transient.","Run RSSHub from a residential/non-datacenter IP, or front it with a proxy that Xueqiu does not flag.","Reduce request frequency / raise config.cache.routeExpire for this route.","If persistent, set a valid logged-in Xueqiu cookie and rework the handler to send it (the route currently relies on the anonymous cookieJar, which is increasingly insufficient).","Inspect data (log it) to see the exact Xueqiu error_code and adjust accordingly."],"exampleFix":"// before\nif (!data.list) {\n    throw new Error('Error occurred, please refresh the page or try again after logging back into your account');\n}\n\n// after — surface Xueqiu's own error code so the cause is diagnosable\nif (!data.list) {\n    throw new Error(`Xueqiu rejected the timeline request (code=${data.error_code ?? 'unknown'}: ${data.error_description ?? 'no list returned'}). The anonymous cookie may be insufficient; retry or supply a logged-in cookie.`);\n}","handlingStrategy":"retry","validationCode":"// Nothing to validate before the call — the anonymous cookie is obtained inline.\n// Best preflight: verify the column page actually exposed SNOWMAN_TARGET\nif (!SNOWMAN_TARGET || !SNOWMAN_TARGET.screen_name) {\n    throw new Error('Xueqiu did not expose SNOWMAN_TARGET on the column page; the anonymous session was likely blocked.');\n}","typeGuard":"function hasTimelineList(data: unknown): data is { list: unknown[] } {\n    return typeof data === 'object' && data !== null && Array.isArray((data as any).list);\n}","tryCatchPattern":"// Xueqiu anti-bot is intermittent; retry with a fresh cookieJar\nfor (let attempt = 0; attempt < 3; attempt++) {\n    const freshJar = new CookieJar();\n    await got(baseUrl, { cookieJar: freshJar });\n    const { data } = await got(`${baseUrl}/statuses/original/timeline.json`, { cookieJar: freshJar, searchParams: { user_id: id, page: 1 } });\n    if (data.list) return data;\n    await new Promise((r) => setTimeout(r, (attempt + 1) * 1500));\n}\nthrow new Error('Xueqiu repeatedly refused the timeline request; supply a logged-in cookie or reduce frequency.');","preventionTips":["Run RSSHub from a residential IP or proxy Xueqiu traffic.","Raise the cache TTL for this route to lower request frequency.","If persistent, configure a logged-in Xueqiu cookie instead of relying on the anonymous cookieJar.","Log data.error_code when list is missing to identify the specific Xueqiu block reason."],"tags":["xueqiu","anti-crawler","cookie","auth","finance"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}