{"record":{"id":"21b88b64c4aed77f","repo":"jackwener/OpenCLI","slug":"weread-official-apiname","errorCode":null,"errorMessage":"weread-official ${apiName}","messagePattern":"weread-official (.+?)","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"clis/weread-official/utils.js","lineNumber":95,"sourceCode":"\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n    let response;\n    try {\n        response = await fetch(WEREAD_GATEWAY_URL, {\n            method: 'POST',\n            headers: {\n                Authorization: `Bearer ${key}`,\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify(body),\n            signal: controller.signal,\n        });\n    }\n    catch (error) {\n        if (error?.name === 'AbortError') {\n            throw new TimeoutError(`weread-official ${apiName}`, Math.round(timeoutMs / 1000));\n        }\n        const detail = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`weread-official ${apiName} request failed`, detail);\n    }\n    finally {\n        clearTimeout(timer);\n    }\n\n    if (!response.ok) {\n        throw new CommandExecutionError(\n            `weread-official ${apiName} HTTP ${response.status}`,\n            'Check WeRead gateway availability and that WEREAD_API_KEY is still valid.',\n        );\n    }\n\n    let payload;\n    try {\n        payload = await response.json();","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread-official/utils.js#L77-L113","documentation":"callGateway wraps fetch failures in two typed errors: TimeoutError when the request was aborted by the configured AbortController (timeoutMs elapsed), and CommandExecutionError otherwise. The message carries the api name so you know which endpoint failed. It exists to convert low-level network errors into actionable CLI errors.","triggerScenarios":"Any fetch exception inside callGateway: AbortError raised after timeoutMs (message becomes 'weread-official <apiName>'), or DNS failure / connection refused / TLS error (detail carries the underlying message).","commonSituations":"Corporate proxy blocking the gateway; slow mobile connection exceeding the timeout; WEREAD gateway temporarily down; firewalled CI runners without egress.","solutions":["Check basic network connectivity and proxy settings (HTTP_PROXY/HTTPS_PROXY).","Retry the command — transient timeouts often resolve; consider increasing the timeout.","Verify https://weread.<domain> gateway status/outage.","If running in CI, add egress rules for the gateway domain."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (!navigator.onLine && typeof navigator !== 'undefined') throw new Error('No network connectivity before calling gateway');","typeGuard":"const isAbort = (e) => e?.name === 'AbortError';","tryCatchPattern":"try {\n  return await callGateway(apiName, params);\n} catch (e) {\n  if (e instanceof TimeoutError) {\n    // exponential backoff, max 3 attempts\n    await sleep(2 ** attempt * 1000);\n    return callGateway(apiName, params);\n  }\n  if (e instanceof CommandExecutionError) console.error(`Gateway request failed: ${e.message}`);\n  throw e;\n}","preventionTips":["Set a generous timeoutMs for slow networks","Wrap repeated gateway calls in a retry-with-backoff helper","Check proxy/VPN before bulk operations","Fail fast with a preflight connectivity check in scripts"],"tags":["network","timeout","http"],"backgroundTag":"request-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}