Hmbown/CodeWhale · error · Error

iLink API ${endpoint} failed: HTTP ${response.status} — ${te

Error message

iLink API ${endpoint} failed: HTTP ${response.status} — ${text.slice(0, 200)}

What it means

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.

Source

Thrown at integrations/weixin-bridge/src/lib.mjs:142

 * 通用 POST 到 iLink API。
 */
export async function apiPost({ baseUrl, endpoint, body, token, timeoutMs, signal }) {
  const url = `${baseUrl.replace(/\/+$/, "")}/${endpoint}`;
  const ms = timeoutMs || DEFAULT_API_TIMEOUT_MS;
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), ms);
  signal?.addEventListener("abort", () => controller.abort(), { once: true });

  try {
    const response = await fetch(url, {
      method: "POST",
      headers: authHeaders({ token }),
      body,
      signal: controller.signal,
    });
    const text = await response.text();
    if (!response.ok) {
      throw new Error(
        `iLink API ${endpoint} failed: HTTP ${response.status} — ${text.slice(0, 200)}`
      );
    }
    return text;
  } finally {
    clearTimeout(timer);
  }
}

/**
 * 通用 GET 到 iLink API(用于轮询扫码状态等)。
 */
export async function apiGet({ baseUrl, endpoint, token, timeoutMs, signal }) {
  const url = `${baseUrl.replace(/\/+$/, "")}/${endpoint}`;
  const ms = timeoutMs || DEFAULT_API_TIMEOUT_MS;
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), ms);
  signal?.addEventListener("abort", () => controller.abort(), { once: true });

View on GitHub (pinned to 8880682c63)

Solutions

  1. Read the embedded body slice first — it names the actual iLink refusal reason
  2. Re-authenticate: obtain a fresh token by re-running the QR login flow, then retry the endpoint
  3. Verify the endpoint name and payload against the iLink API docs for that status code
  4. If 5xx persists, back off — the iLink service is failing upstream

Example fix

// before: reuse a token saved days ago
const text = await iLinkPost('/message/send', body, { token: staleToken });
// after: refresh after login
const { token } = await qrLogin();
const text = await iLinkPost('/message/send', body, { token });
Defensive patterns

Strategy: try-catch

Validate before calling

if (!token || typeof token !== 'string' || !token.trim()) {
  throw new Error('iLink token missing — run the QR login flow before calling iLink APIs');
}

Try / catch

try {
  const text = await iLinkPost(endpoint, body, { token });
} catch (error) {
  const status = Number(error.message.match(/HTTP (\d+)/)?.[1]);
  if (status === 401 || status === 403) {
    token = await refreshILoginToken();
    return iLinkPost(endpoint, body, { token });
  }
  throw error;
}

Prevention

When it happens

Trigger: 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).

Common situations: A WeChat QR-login session token going stale between polls; environment switch invalidating cached tokens; payload schema drift after an iLink API update.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/44a7c1d7016490c1. Report an issue: GitHub.