{"record":{"id":"1d87a5021c1fe717","repo":"jackwener/OpenCLI","slug":"1point3acres-request-failed-error-message-e","errorCode":null,"errorMessage":"1point3acres request failed: ${error?.message || error}","messagePattern":"1point3acres request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/1point3acres/utils.js","lineNumber":57,"sourceCode":"\nconst UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0 Safari/537.36';\n\n/** Fetch a GBK-encoded Discuz page and return decoded UTF-8 HTML. */\nexport async function fetchHtml(url, { headers = {}, cookie = '' } = {}) {\n    let res;\n    try {\n        res = await fetch(url, {\n            headers: {\n                'User-Agent': UA,\n                'Accept': 'text/html,application/xhtml+xml',\n                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',\n                ...(cookie ? { Cookie: cookie } : {}),\n                ...headers,\n            },\n            redirect: 'follow',\n        });\n    } catch (error) {\n        throw new CommandExecutionError(`1point3acres request failed: ${error?.message || error}`);\n    }\n    if (!res.ok) {\n        throw new CommandExecutionError(`1point3acres request failed: HTTP ${res.status} ${res.statusText} from ${url}`);\n    }\n    const buf = await res.arrayBuffer();\n    return new TextDecoder('gbk').decode(buf);\n}\n\n/** Pull cookie string from the live browser session for this domain.\n *  Discuz auth cookies (4Oaf_61d6_*, session) are HttpOnly and set on the\n *  root domain `.1point3acres.com`, so we need `getCookies` (not document.cookie)\n *  AND we need to query both host + root domain and merge.\n */\nexport async function getCookie(page) {\n    if (!page) return '';\n    const seen = new Map();\n    if (typeof page.getCookies === 'function') {\n        for (const opts of [{ domain: 'www.1point3acres.com' }, { domain: '.1point3acres.com' }]) {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/1point3acres/utils.js#L39-L75","documentation":"CommandExecutionError from fetchHtml wrapping any network-level failure of the 1point3acres HTTP request — DNS failure, connection refused/timeout, TLS errors, or aborts. The underlying error's message is interpolated into '1point3acres request failed: <reason>'. Separately, non-2xx responses produce a sibling error with the HTTP status. The response body is decoded as GBK, matching the forum's encoding.","triggerScenarios":"No network / DNS resolution failure for www.1point3acres.com; server or CDN down; connection timeout; ECONNRESET; request aborted; proxy misconfiguration (HTTP(S)_PROXY env pointing at a dead proxy); IPv6 connectivity issues.","commonSituations":"Corporate firewall or GFW blocking the site; running from a region where the forum is unreachable; transient CDN outages; container without outbound internet; wrong proxy env vars; expired DNS in long-running processes.","solutions":["Read the wrapped message after '1point3acres request failed:' to identify the root cause (ENOTFOUND, ECONNREFUSED, ETIMEDOUT, cert error)","Check basic connectivity: curl -I https://www.1point3acres.com/bbs/forum.php","Retry with backoff — transient network errors and CDN hiccups are common","Check HTTP(S)_PROXY / HTTPS_PROXY / NO_PROXY env vars if behind a corporate network or VPN","If a specific HTTP status is reported instead (HTTP 403/503), it's an anti-bot block — slow down, add/refresh cookies, or use a session with login","Verify DNS: nslookup www.1point3acres.com"],"exampleFix":"// before\nconst html = await fetchHtml(url);  // ENOTFOUND → CommandExecutionError\n// after\nimport { CommandExecutionError } from './errors.js';\ntry {\n  const html = await fetchHtml(url);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /ECONN|ENOTFOUND|ETIMEDOUT/.test(e.message)) {\n    await new Promise(r => setTimeout(r, 2000));\n    const html = await fetchHtml(url);  // retry once\n  } else throw e;\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"import { CommandExecutionError } from 'clis/1point3acres/errors.js';\nasync function fetchWithRetry(url, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await fetchHtml(url);\n    } catch (e) {\n      const transient = e instanceof CommandExecutionError &&\n        /ECONNRESET|ETIMEDOUT|ENOTFOUND|ECONNREFUSED|socket|network/i.test(e.message);\n      if (transient && i < attempts - 1) {\n        await new Promise(r => setTimeout(r, 1000 * 2 ** i));\n        continue;\n      }\n      throw e;\n    }\n  }\n}","preventionTips":["Add exponential-backoff retries around fetchHtml for transient failures","Check proxy env vars (HTTPS_PROXY/NO_PROXY) when behind corporate networks or VPN","Rate-limit requests to avoid tripping anti-bot blocks that escalate into failures","Pre-flight connectivity check (curl -I) in CI before batch scraping","Log the wrapped root cause (after '1point3acres request failed:') to distinguish DNS vs timeout vs TLS"],"tags":["network","http-request","scraping"],"backgroundTag":"connection-refused","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}