{"record":{"id":"0f846a0117e8d4c4","repo":"jackwener/OpenCLI","slug":"label-request-failed-outcome-detail","errorCode":null,"errorMessage":"${label} request failed: ${outcome.detail}","messagePattern":"(.+?) request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/jike/utils.js","lineNumber":79,"sourceCode":"        headers,\n        body: JSON.stringify(${JSON.stringify(requestBody)}),\n      });\n      let body;\n      try {\n        body = await response.json();\n      } catch (error) {\n        return { kind: 'json', status: response.status, detail: String(error?.message || error) };\n      }\n      return { kind: 'response', status: response.status, body };\n    } catch (error) {\n      return { kind: 'transport', detail: String(error?.message || error) };\n    }\n  })()`);\n  if (outcome?.kind === 'auth' || outcome?.status === 401 || outcome?.status === 403) {\n    throw new AuthRequiredError('web.okjike.com', outcome?.detail || `${label} returned HTTP ${outcome?.status}`);\n  }\n  if (outcome?.kind === 'transport') {\n    throw new CommandExecutionError(`${label} request failed: ${outcome.detail}`);\n  }\n  if (outcome?.kind === 'json') {\n    throw new CommandExecutionError(`${label} returned invalid JSON: ${outcome.detail}`);\n  }\n  if (outcome?.kind !== 'response' || !Number.isInteger(outcome.status)) {\n    throw new CommandExecutionError(`${label} returned an unexpected response`);\n  }\n  if (outcome.status < 200 || outcome.status >= 300) {\n    throw new CommandExecutionError(`${label} returned HTTP ${outcome.status}`);\n  }\n  return outcome.body;\n}\n\n/**\n * 注入浏览器 evaluate 的 JS 函数字符串。\n * 从 React fiber 树中向上最多走 10 层，找到含 id 字段的 props.data。\n */\nexport const getPostDataJs = `","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jike/utils.js#L61-L97","documentation":"postJikeApi wraps HTTP calls to web.okjike.com's API. When the fetch fails at the transport level (network error, DNS failure, connection reset, TLS error) the outcome object has kind 'transport', and the helper throws a CommandExecutionError with the label and underlying detail instead of returning a body. This distinguishes network-level failure from HTTP error statuses or malformed JSON.","triggerScenarios":"Calling any jike API helper (e.g. body('postJikeApi',...)) when the request to web.okjike.com cannot complete: no internet, DNS resolution failure, proxy misconfiguration, TLS handshake failure, or the connection being refused/reset before an HTTP response is received.","commonSituations":"Developer offline or on a captive portal; corporate proxy blocking web.okjike.com; firewall/DNS issues; jike server outage; wrong base URL after a site endpoint change.","solutions":["Check network connectivity and that https://web.okjike.com is reachable (curl -I https://web.okjike.com)","Inspect outcome.detail in the message for the underlying fetch error (ENOTFOUND, ECONNRESET, certificate errors) and fix accordingly","If behind a proxy, configure HTTP(S)_PROXY or the CLI's proxy settings correctly","Retry after a short wait if jike is having a transient outage","If it persists, confirm the API endpoint used by the CLI has not changed"],"exampleFix":"// before\nconst body = await body('postJikeApi', '/api/feed', {}); // throws on any transport failure\n// after\nlet body;\ntry {\n  body = await body('postJikeApi', '/api/feed', {});\n} catch (err) {\n  if (err instanceof CommandExecutionError && /request failed/.test(err.message)) {\n    await sleep(2000); // transient network issue: retry once\n    body = await body('postJikeApi', '/api/feed', {});\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"const reachable = await fetch('https://web.okjike.com/', { method: 'HEAD' }).then(r => r.ok).catch(() => false);\nif (!reachable) throw new Error('web.okjike.com unreachable — check network/proxy before calling');","typeGuard":"function isTransportFailure(err) {\n  return err instanceof CommandExecutionError && /request failed:/.test(err.message);\n}","tryCatchPattern":"try {\n  const body = await body('postJikeApi', path, payload);\n} catch (err) {\n  if (isTransportFailure(err)) {\n    // network-level: retry with backoff or surface a friendly offline message\n  } else throw err;\n}","preventionTips":["Check connectivity before batch API calls","Configure proxy env vars when behind a corporate proxy","Add retry with exponential backoff for transient transport errors","Monitor jike status for outages before large runs"],"tags":["network","http","command-execution-error","jike"],"backgroundTag":"network-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}