{"record":{"id":"d67cca4f72d89160","repo":"jackwener/OpenCLI","slug":"bbs-hupu-com","errorCode":null,"errorMessage":"bbs.hupu.com","messagePattern":"bbs\\.hupu\\.com","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/hupu/utils.js","lineNumber":309,"sourceCode":"          error: error instanceof Error ? error.message : String(error)\n        };\n      }\n    })()\n  `;\n}\n/**\n * Execute authenticated Hupu JSON requests inside the browser page so\n * cookies and the thread referer come from the live logged-in session.\n */\nexport async function postHupuJson(page, tid, apiUrl, body, actionLabel, mode = 'default') {\n    const referer = getHupuThreadUrl(tid);\n    await page.goto(referer);\n    const result = await page.evaluate(buildBrowserJsonPostScript(apiUrl, body, mode));\n    if (!result || typeof result !== 'object') {\n        throw new CommandExecutionError(`${actionLabel} failed: invalid browser response`);\n    }\n    if (result.status === 401 || result.status === 403) {\n        throw new AuthRequiredError('bbs.hupu.com', `${actionLabel} failed: please log in to Hupu first`);\n    }\n    if (result.error) {\n        throw new CommandExecutionError(`${actionLabel} failed: ${result.error}`);\n    }\n    if (!result.ok) {\n        const detail = result.data?.msg || result.data?.message || `HTTP ${result.status ?? 'unknown'}`;\n        throw new CommandExecutionError(`${actionLabel} failed: ${detail}`);\n    }\n    return result.data ?? {};\n}\n","sourceCodeStart":291,"sourceCodeEnd":320,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hupu/utils.js#L291-L320","documentation":"postHupuJson maps the in-page fetch's HTTP status to errors: a 401 or 403 response from a bbs.hupu.com API (like/unlike/reply) raises AuthRequiredError with domain 'bbs.hupu.com' and message '<action> failed: please log in to Hupu first'. The observed message 'bbs.hupu.com' is the AuthRequiredError's domain field, indicating the Hupu session is unauthenticated — the site rejected the authenticated POST.","triggerScenarios":"Running a write command (hupu like/unlike/reply) whose in-browser POST returns HTTP 401 or 403, typically because cookies are missing, expired, or the account is not logged in in the automated browser session.","commonSituations":"Expired Hupu session cookies (the CLI uses Strategy.COOKIE auth), running the command without logging in first, cookies cleared or rotated by the browser, or Hupu's anti-bot/WAF returning 403 to requests lacking valid session/risk tokens (shumei_id/thumbcache).","solutions":["Log in to Hupu in the automated browser (or re-run the CLI's login command) to refresh cookies, then retry.","Verify cookies are actually loaded (Strategy.COOKIE) and not expired — check the session/cookie store the CLI uses.","Open bbs.hupu.com in the session and confirm you appear logged in before running write commands.","If you get 403 while logged in, risk-control tokens may be missing — browse the thread normally so .thumbcache_/smidV2 cookies are set, then retry.","Retry later if Hupu's WAF is rate-limiting your IP."],"exampleFix":"// before\nawait cliRun(['hupu', 'unlike', tid, pid, '--fid', fid]); // AuthRequiredError: bbs.hupu.com\n// after — ensure login state before write ops\nif (!(await isLoggedIn(page, 'bbs.hupu.com'))) {\n  await runLogin('hupu');\n}\nawait cliRun(['hupu', 'unlike', tid, pid, '--fid', fid]);","handlingStrategy":"try-catch","validationCode":"// check login state before any authenticated write\nconst loggedIn = await page.evaluate(() =>\n  document.cookie.split('; ').some(c => c.startsWith('ua=')) ||\n  Boolean(document.querySelector('.login-after, [class*=\"user\"]')));\nif (!loggedIn) throw new AuthRequiredError('bbs.hupu.com', 'log in before running write commands');","typeGuard":"function isAuthError(err) {\n  return err instanceof AuthRequiredError ||\n    (err && err.domain === 'bbs.hupu.com') ||\n    /please log in to Hupu first/.test(err?.message || '');\n}","tryCatchPattern":"try {\n  await hupuUnlike(tid, pid, fid);\n} catch (err) {\n  if (isAuthError(err)) {\n    await runHupuLogin();      // refresh cookies / interactive login\n    return hupuUnlike(tid, pid, fid); // retry once with fresh session\n  }\n  throw err;\n}","preventionTips":["Run the login command and confirm a valid session before any write (like/unlike/reply).","Check cookie expiry periodically; Hupu sessions expire and silently break writes.","Browse a thread normally first so risk-control cookies (.thumbcache_, smidV2, ua) are populated.","Treat 403-while-logged-in as anti-bot risk control: slow down, avoid rapid batch writes.","Catch AuthRequiredError explicitly so it is not swallowed by generic error wrappers."],"tags":["hupu","authentication","http-401","http-403","cookies"],"backgroundTag":"auth-required-login-first","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}