{"record":{"id":"c2aa90bf9132c2bb","repo":"jackwener/OpenCLI","slug":"read-hupu-mentions-failed-result-error-unkn","errorCode":null,"errorMessage":"Read Hupu mentions failed: ${result.error || 'unknown error'}","messagePattern":"Read Hupu mentions failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/hupu/mentions.js","lineNumber":137,"sourceCode":"              pageStr: nextPageStr\n            }\n          };\n        } catch (error) {\n          return {\n            ok: false,\n            error: error instanceof Error ? error.message : String(error)\n          };\n        }\n      })()\n    `);\n        if (!result || typeof result !== 'object') {\n            throw new CommandExecutionError('Read Hupu mentions failed: invalid browser response');\n        }\n        if (result.status === 401 || result.status === 403) {\n            throw new AuthRequiredError('my.hupu.com', 'Read Hupu mentions failed: please log in to Hupu first');\n        }\n        if (!result.ok) {\n            throw new CommandExecutionError(`Read Hupu mentions failed: ${result.error || 'unknown error'}`);\n        }\n        const items = result.data?.items || [];\n        return items.map((item) => {\n            const tid = item.tid ? String(item.tid) : '';\n            const pid = item.pid ? String(item.pid) : '';\n            return {\n                time: item.publishTime || '',\n                username: item.username || '',\n                thread_title: item.threadTitle || '',\n                post_content: stripHtml(item.postContent || ''),\n                quote_content: stripHtml(item.quoteContent || ''),\n                url: tid ? `https://bbs.hupu.com/${tid}.html` : '',\n                reply_url: tid && pid ? `https://bbs.hupu.com/${tid}.html?pid=${pid}` : '',\n                tid,\n                pid,\n                topic_id: item.topicId ? String(item.topicId) : '',\n                msg_type: item.msgType ?? '',\n                has_next_page: result.data?.hasNextPage ?? false,","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hupu/mentions.js#L119-L155","documentation":"CommandExecutionError is thrown when the in-page scrape of the Hupu mentions API reports ok:false for any reason other than 401/403 auth failure. The browser-side code converts non-OK HTTP responses, business error codes (api.code > 1), and any thrown fetch/parse exception into {ok:false, error}, and this line re-raises it host-side. It is a generic wrapper for network, API, or parsing failures during the mentions read.","triggerScenarios":"HTTP != 2xx from getMentionedRemindList (e.g. 5xx); Hupu API business code > 1 (e.g. risk-control or parameter errors); fetch network failure inside the page; non-JSON response body; any exception thrown in the evaluate loop, all surfacing as result.error.","commonSituations":"Transient Hupu server errors or rate limiting; Hupu changed the private pcmapi endpoint or response shape; page navigation/interruption cancels the fetch; anti-bot checks returning an error body; network outage while the browser ran the request.","solutions":["Read the wrapped result.error text to identify the underlying cause (HTTP status vs API msg).","Retry after a short delay if the error is transient (5xx, network, rate limit).","Confirm you can load https://my.hupu.com/message in the browser and the API returns data normally.","If Hupu changed the API/shape, update the endpoint or parsing logic in clis/hupu/mentions.js."],"exampleFix":"// before\nconst result = await page.evaluate(script); // throws opaque CommandExecutionError\n// after: catch and retry transient failures\ntry {\n  const result = await page.evaluate(script);\n} catch (e) {\n  if (/HTTP 5|network/i.test(e.message)) await sleep(3000); // then retry\n  throw e;\n}","handlingStrategy":"retry","validationCode":"// Sanity-check connectivity and params before invoking\nif (!(Number.isInteger(limit) && limit >= 1 && limit <= 100)) throw new Error('limit must be 1-100');\nif (!(Number.isInteger(maxPages) && maxPages >= 1 && maxPages <= 10)) throw new Error('max_pages must be 1-10');\nconst res = await fetch('https://my.hupu.com/pcmapi/pc/space/v1/getMentionedRemindList?plate=1', { credentials: 'include' });\nif (!res.ok) console.warn('Hupu API currently unhealthy: HTTP', res.status);","typeGuard":"function isBrowserScrapeResult(r) {\n  return r !== null && typeof r === 'object' && typeof r.ok === 'boolean';\n}","tryCatchPattern":"for (let attempt = 1; attempt <= 3; attempt++) {\n  try { return await run('hupu mentions', { limit, max_pages }); }\n  catch (e) {\n    if (e.name === 'AuthRequiredError') throw e; // do not retry auth\n    if (attempt === 3) throw e;\n    await new Promise(r => setTimeout(r, 2000 * attempt)); // backoff for 5xx/network\n  }\n}","preventionTips":["Inspect result.error in the message to distinguish transient (5xx/network) from permanent (API change) causes.","Add exponential backoff retries for network/5xx errors only.","Verify the my.hupu.com pcmapi endpoint still works manually when errors persist.","Keep limit/max_pages within documented bounds (1-100, 1-10) to avoid parameter-driven failures."],"tags":["network","hupu","scraping","api-error"],"backgroundTag":"api-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}