{"record":{"id":"078027ecfd4e2036","repo":"jackwener/OpenCLI","slug":"dongchedi-contexthint-http-resp-status","errorCode":null,"errorMessage":"dongchedi ${contextHint} HTTP ${resp.status}","messagePattern":"dongchedi (.+?) HTTP (.+?)","errorType":"http","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/dongchedi/utils.js","lineNumber":89,"sourceCode":" * Throws typed errors so callers can let them propagate.\n */\nexport async function dcdFetchPageProps(path, contextHint) {\n    let resp;\n    try {\n        resp = await fetch(`${DCD_BASE}${path}`, {\n            headers: {\n                'User-Agent': UA,\n                Referer: `${DCD_BASE}/`,\n                'Accept-Language': 'zh-CN,zh;q=0.9',\n            },\n        });\n    } catch (err) {\n        throw new CommandExecutionError(\n            `dongchedi ${contextHint} network error: ${err?.message || err}`,\n        );\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`dongchedi ${contextHint} HTTP ${resp.status}`);\n    }\n    const html = await resp.text();\n    const pp = extractPageProps(html);\n    if (!pp) {\n        throw new CommandExecutionError(\n            `dongchedi ${contextHint} returned no __NEXT_DATA__`,\n            'Dongchedi likely changed its page structure, or the request hit an anti-bot page.',\n        );\n    }\n    if (isFallbackShell(pp)) {\n        throw new CommandExecutionError(\n            `dongchedi ${contextHint}`,\n            'Dongchedi served its empty fallback shell — the id may not exist or the URL form changed.',\n        );\n    }\n    return pp;\n}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dongchedi/utils.js#L71-L107","documentation":"A CommandExecutionError raised in dcdFetchPageProps (clis/dongchedi/utils.js:89) when dongchedi.com responded but with a non-2xx status (`!resp.ok`). The message embeds the HTTP status code plus the context hint so the developer knows which command's request failed and how.","triggerScenarios":"Any dongchedi command when the server returns 403 (anti-bot/WAF rejection), 429 (rate limiting after rapid repeated calls), 404 (bad URL form or nonexistent series path), or 5xx (server-side outage).","commonSituations":"Scraping in a tight loop until rate-limited (429), requests flagged by ByteDance's WAF (403) due to datacenter IPs or unusual headers, typos producing invalid paths (404), or dongchedi having a temporary outage (5xx).","solutions":["Read the status code in the message: 403/429 → slow down, add delays between requests, or retry later from a residential IP; 404 → verify the series id / URL form; 5xx → retry later.","Add exponential backoff with jitter around dcdFetchPageProps for 429/5xx responses.","Confirm the URL by opening `https://www.dongchedi.com<path>` in a browser — if the browser also fails, the id or path is wrong.","Keep the default browser-like User-Agent/Referer headers the library already sends; do not strip them.","Catch CommandExecutionError and branch on the parsed status to give users an actionable message."],"exampleFix":"// before: hammering the API until 429\nfor (const id of ids) await dcd.specs(id);\n// after: throttle with backoff\nfor (const id of ids) {\n  await sleep(1500);\n  try { await dcd.specs(id); } catch (e) { if (String(e).includes('429')) await retryWithBackoff(); }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const pp = await dcdFetchPageProps(path, hint);\n} catch (err) {\n  const m = err.message.match(/HTTP (\\d{3})/);\n  if (m && (m[1] === '429' || m[1].startsWith('5'))) await retryWithBackoff();\n  else if (m && m[1] === '404') reportBadPath(path);\n  else throw err;\n}","preventionTips":["Throttle requests (e.g. ≥1s apart) to avoid 429 rate limiting.","Keep the browser-like User-Agent/Referer headers the library sends.","Validate series ids/URL paths before fetching to avoid 404s.","Treat 403 as an IP/WAF problem — switch networks or slow down, don't hammer."],"tags":["http","network","rate-limit","dongchedi"],"backgroundTag":"http-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}