{"record":{"id":"7bcda9b51dec044d","repo":"jackwener/OpenCLI","slug":"arxiv-api-http-resp-status","errorCode":null,"errorMessage":"arXiv API HTTP ${resp.status}","messagePattern":"arXiv API HTTP (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/arxiv/utils.js","lineNumber":13,"sourceCode":"/**\n * arXiv adapter utilities.\n *\n * arXiv exposes a public Atom/XML API — no key required.\n * https://info.arxiv.org/help/api/index.html\n */\nimport { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';\nexport const ARXIV_BASE = 'https://export.arxiv.org/api/query';\nconst ARXIV_CATEGORY_PATTERN = /^[a-z]+(?:-[a-z]+)*(?:\\.[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)?$/;\nexport async function arxivFetch(params) {\n    const resp = await fetch(`${ARXIV_BASE}?${params}`);\n    if (!resp.ok) {\n        throw new CommandExecutionError(`arXiv API HTTP ${resp.status}`, 'Check your search term or paper ID');\n    }\n    return resp.text();\n}\nexport function normalizeArxivLimit(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const limit = Number(raw);\n    if (!Number.isInteger(limit) || limit <= 0) {\n        throw new ArgumentError(`arxiv ${label} must be a positive integer`);\n    }\n    if (limit > maxValue) {\n        throw new ArgumentError(`arxiv ${label} must be <= ${maxValue}`);\n    }\n    return limit;\n}\nexport function normalizeArxivCategory(value) {\n    const category = String(value || '').trim();\n    if (!ARXIV_CATEGORY_PATTERN.test(category)) {\n        throw new ArgumentError(`Invalid arXiv category \"${value}\". Examples: cs.CL, cs.LG, math.PR, q-bio.NC, physics.comp-ph`);","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/arxiv/utils.js#L1-L31","documentation":"CommandExecutionError thrown by arxivFetch when the arXiv export API responds with a non-OK HTTP status. The library treats any failed fetch of https://export.arxiv.org/api/query as a command execution failure and surfaces the HTTP status code in the message. It indicates the request itself reached the server but was rejected (4xx/5xx), e.g. a malformed query string or arXiv-side outage.","triggerScenarios":"Any call path that fetches from the arXiv API (search by term, paper ID, category listing) where the server returns a non-2xx response: malformed params, rate limiting (HTTP 429/503), or arXiv export API downtime.","commonSituations":"arXiv throttles clients that poll too fast (503 with Retry-After); temporary outages of export.arxiv.org; constructing an invalid query string upstream so the API rejects it; network proxies returning 4xx/5xx.","solutions":["Check the message's HTTP status: if 503/429, wait (arXiv asks for ~3s between requests) and retry with backoff.","Verify the search term or paper ID is well-formed (e.g. paper IDs like 2401.12345v1).","Check https://status.arxiv.org or hit the ARXIV_BASE URL in a browser to confirm the API is up.","If behind a corporate proxy, confirm the proxy allows export.arxiv.org."],"exampleFix":"// before\nconst text = await arxivFetch('search_query=bad term');\n// after: retry with delay on 5xx/429\ntry {\n  const text = await arxivFetch('search_query=all:electron&max_results=5');\n} catch (e) {\n  await new Promise(r => setTimeout(r, 3000));\n  const text = await arxivFetch('search_query=all:electron&max_results=5');\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const xml = await arxivFetch(params);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /HTTP (429|503)/.test(e.message)) {\n    await sleep(3000); // honor arXiv rate limits, then retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["Space arXiv requests at least ~3 seconds apart to avoid 503 throttling.","Validate query params before building the request URL.","Implement exponential backoff for 429/5xx responses.","Monitor arXiv API status before bulk jobs."],"tags":["network","http-error","api"],"backgroundTag":"upstream-api-http-error","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}