{"record":{"id":"b1151acb68315d73","repo":"santifer/career-ops","slug":"timeout","errorCode":"TIMEOUT","errorMessage":"H-1B API timeout${label} after ${timeoutMs}ms: ${url}","messagePattern":"H-1B API timeout(.+?) after (.+?)ms: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/h1b-sponsor/lib/api.mjs","lineNumber":298,"sourceCode":"    if (read.oversized) return { kind: 'toobig' };\n    try {\n      return { kind: 'json', body: JSON.parse(read.text) };\n    } catch {\n      return { kind: 'badjson' };\n    }\n  });\n\n  const timeoutError = (label) => {\n    const e = new Error(`H-1B API timeout${label} after ${timeoutMs}ms: ${url}`);\n    e.code = 'TIMEOUT';\n    return e;\n  };\n\n  let out;\n  try {\n    out = await attempt();\n  } catch (err) {\n    if (err && err.name === 'AbortError') throw timeoutError('');\n    throw err;\n  }\n\n  if (out.kind === 'rate') {\n    await sleep(Math.min(out.waitMs, MAX_RETRY_WAIT_MS));\n    try {\n      out = await attempt();\n    } catch (err) {\n      if (err && err.name === 'AbortError') throw timeoutError(' on retry');\n      throw err;\n    }\n    if (out.kind === 'rate') {\n      const e = new Error(`H-1B API rate limited: ${url}`);\n      e.code = 'RATE_LIMIT';\n      throw e;\n    }\n  }\n","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/plugins/h1b-sponsor/lib/api.mjs#L280-L316","documentation":"requestJson in the h1b-sponsor plugin aborts the HTTP request after timeoutMs and throws a TIMEOUT-coded error naming the URL. The initial attempt is wrapped: an AbortError from the abort controller is converted into this timeout error (empty label), while any other error propagates unchanged. It signals the H-1B API endpoint did not respond within the configured budget.","triggerScenarios":"Calling any plugin API helper (e.g. fetching employer sponsorship data) where fetch does not complete within timeoutMs; the AbortController fires, attempt() rejects with AbortError, and timeoutError('') is thrown.","commonSituations":"Slow or rate-pressured H-1B API endpoints; offline/proxied environments where the connection hangs instead of failing fast; too-low timeoutMs for large queries; corporate firewalls silently dropping packets.","solutions":["Increase the request timeout (timeoutMs option/env) for large or slow queries","Check network/proxy reachability of the API host from this machine","Retry the request — transient slowness is common; the plugin already retries once on rate-limit responses","Check the H-1B API status/outage before further calls","If behind a proxy, configure proxy env vars so the request is routed correctly instead of hanging"],"exampleFix":"// before\ndata = await requestJson(url, { timeoutMs: 3000 });\n// after\ntry {\n  data = await requestJson(url, { timeoutMs: 15000 });\n} catch (e) {\n  if (e.code === 'TIMEOUT') data = await requestJson(url, { timeoutMs: 30000 });\n  else throw e;\n}","handlingStrategy":"retry","validationCode":"// pre-check reachability before the real call\nconst ok = await fetch(BASE_URL, { method: 'HEAD', signal: AbortSignal.timeout(5000) })\n  .then(r => r.ok).catch(() => false);\nif (!ok) throw new Error('H-1B API unreachable, skip call');","typeGuard":"const isApiTimeout = (e) => e?.code === 'TIMEOUT' || e?.name === 'AbortError';","tryCatchPattern":"try {\n  data = await requestJson(url, { timeoutMs: 15000 });\n} catch (e) {\n  if (isApiTimeout(e)) return fallbackOrRetry(e, url);\n  throw e;\n}","preventionTips":["Set realistic timeoutMs for large queries; never ship sub-5s defaults","Wrap calls with your own exponential-backoff retry for code TIMEOUT","Cache responses to cut repeat calls to slow endpoints","Monitor API status and circuit-break after repeated timeouts","Verify proxy/firewall reachability before batch runs"],"tags":["network","timeout","http","api"],"backgroundTag":"request-timeout","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}