{"record":{"id":"44a7c1d7016490c1","repo":"Hmbown/CodeWhale","slug":"ilink-api-endpoint-failed-http-response-stat","errorCode":null,"errorMessage":"iLink API ${endpoint} failed: HTTP ${response.status} — ${text.slice(0, 200)}","messagePattern":"iLink API (.+?) failed: HTTP (.+?) — (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/weixin-bridge/src/lib.mjs","lineNumber":142,"sourceCode":" * 通用 POST 到 iLink API。\n */\nexport async function apiPost({ baseUrl, endpoint, body, token, timeoutMs, signal }) {\n  const url = `${baseUrl.replace(/\\/+$/, \"\")}/${endpoint}`;\n  const ms = timeoutMs || DEFAULT_API_TIMEOUT_MS;\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), ms);\n  signal?.addEventListener(\"abort\", () => controller.abort(), { once: true });\n\n  try {\n    const response = await fetch(url, {\n      method: \"POST\",\n      headers: authHeaders({ token }),\n      body,\n      signal: controller.signal,\n    });\n    const text = await response.text();\n    if (!response.ok) {\n      throw new Error(\n        `iLink API ${endpoint} failed: HTTP ${response.status} — ${text.slice(0, 200)}`\n      );\n    }\n    return text;\n  } finally {\n    clearTimeout(timer);\n  }\n}\n\n/**\n * 通用 GET 到 iLink API（用于轮询扫码状态等）。\n */\nexport async function apiGet({ baseUrl, endpoint, token, timeoutMs, signal }) {\n  const url = `${baseUrl.replace(/\\/+$/, \"\")}/${endpoint}`;\n  const ms = timeoutMs || DEFAULT_API_TIMEOUT_MS;\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), ms);\n  signal?.addEventListener(\"abort\", () => controller.abort(), { once: true });","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/weixin-bridge/src/lib.mjs#L124-L160","documentation":"iLinkPost wraps POSTs to the iLink API with an AbortController timeout; any non-ok response throws `iLink API ${endpoint} failed: HTTP ${response.status} — ${text.slice(0, 200)}`. The endpoint name, HTTP status, and the first 200 chars of the response body are embedded, so the body slice is the diagnostic — iLink error payloads explain the refusal. A timeout instead surfaces as an AbortError from fetch, not this error.","triggerScenarios":"An expired or invalid iLink token passed via authHeaders({ token }); calling a login/message endpoint with a payload the API rejects (4xx); upstream iLink failures (5xx).","commonSituations":"A WeChat QR-login session token going stale between polls; environment switch invalidating cached tokens; payload schema drift after an iLink API update.","solutions":["Read the embedded body slice first — it names the actual iLink refusal reason","Re-authenticate: obtain a fresh token by re-running the QR login flow, then retry the endpoint","Verify the endpoint name and payload against the iLink API docs for that status code","If 5xx persists, back off — the iLink service is failing upstream"],"exampleFix":"// before: reuse a token saved days ago\nconst text = await iLinkPost('/message/send', body, { token: staleToken });\n// after: refresh after login\nconst { token } = await qrLogin();\nconst text = await iLinkPost('/message/send', body, { token });","handlingStrategy":"try-catch","validationCode":"if (!token || typeof token !== 'string' || !token.trim()) {\n  throw new Error('iLink token missing — run the QR login flow before calling iLink APIs');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const text = await iLinkPost(endpoint, body, { token });\n} catch (error) {\n  const status = Number(error.message.match(/HTTP (\\d+)/)?.[1]);\n  if (status === 401 || status === 403) {\n    token = await refreshILoginToken();\n    return iLinkPost(endpoint, body, { token });\n  }\n  throw error;\n}","preventionTips":["Refresh login tokens proactively before expiry rather than on first failure","Log the full message — it already carries endpoint, status, and a body prefix sufficient for diagnosis"],"tags":["network","api","weixin","ilink","http"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}