{"record":{"id":"080cbf5d00e33711","repo":"santifer/career-ops","slug":"glints-http-err-status-detail","errorCode":null,"errorMessage":"glints: HTTP ${err.status} — ${detail}","messagePattern":"glints: HTTP (.+?) — (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"providers/glints.mjs","lineNumber":176,"sourceCode":"        'user-agent': BROWSER_LIKE_USER_AGENT,\n        'origin': 'https://glints.com',\n        'referer': 'https://glints.com/id/opportunities/jobs/explore',\n      },\n      body,\n      redirect: 'error',\n    });\n    return res;\n  } catch (err) {\n    // On POST, some servers return non-JSON errors; attempt text fallback\n    if (err.status && err.body) {\n      let detail = '';\n      try {\n        const parsed = JSON.parse(err.body);\n        detail = parsed.errors?.[0]?.message || err.body.slice(0, 200);\n      } catch {\n        detail = err.body.slice(0, 200);\n      }\n      throw new Error(`glints: HTTP ${err.status} — ${detail}`);\n    }\n    throw err;\n  }\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'glints',\n\n  detect(_entry) {\n    // Glints is a job board aggregator, not a company ATS.\n    // Auto-detection is intentionally not supported —\n    // use `provider: glints` explicitly in portals.yml.\n    return null;\n  },\n\n  async fetch(entry, ctx) {\n    const apiUrl = entry.api || DEFAULT_API;","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/glints.mjs#L158-L194","documentation":"graphqlPage issues the reverse-engineered GraphQL search request against Glints' v2-alc endpoint. When the HTTP layer raises an error carrying a status and body, the code tries JSON.parse(err.body) to extract errors[0].message as the detail; if that fails it falls back to the first 200 chars of the body, then throws 'glints: HTTP {status} — {detail}'. The message surfaces the upstream status plus whatever error detail the server returned.","triggerScenarios":"The Glints GraphQL endpoint returns a non-2xx response: a 4xx for a malformed/changed query (the searchJobsV3 schema is reverse-engineered and may change), a 403/429 from bot protection or rate limiting, or a 5xx outage. graphqlPage then throws with the status and body-derived detail.","commonSituations":"Glints renames or restructures the searchJobsV3 operation (schema drift — the file explicitly warns the schema may change); rate limiting or Cloudflare blocking the browser-like user-agent; transient 5xx during an incident; pageSize/maxPages pushing the server to reject a request.","solutions":["Read the detail after 'HTTP <status> —' in the message: it contains the GraphQL error message or raw body prefix identifying the server-side complaint","For 4xx schema drift, re-capture the current query from glints.com/id devtools and update graphqlQuery (custom query field on the entry) or the provider's DEFAULT_GRAPHQL_QUERY","For 403/429, back off and retry later, reduce maxPages/pageSize, and confirm no proxy is interfering; consider being gentler with request frequency","For 5xx, treat as transient — retry after a delay; check glints.com status if it persists"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight schema check before paginating:\nconst probe = await fetch('https://glints.com/api/v2-alc/graphql', { method: 'POST', headers: {'content-type':'application/json'}, body: JSON.stringify({ query: DEFAULT_GRAPHQL_QUERY, variables: { data: buildSearchCondition({}) } }) });\nif (!probe.ok) console.warn(`glints GraphQL probe returned ${probe.status} — schema or access issue`);","typeGuard":"function isGlintsHttpError(e) { return e && typeof e.status === 'number' && typeof e.body === 'string'; }","tryCatchPattern":"try {\n  const page = await graphqlPage(variables, offset);\n} catch (e) {\n  const m = /glints: HTTP (\\d+)/.exec(e.message);\n  if (m && (m[1] === '429' || m[1].startsWith('5'))) {\n    await sleep(backoffMs);\n    return graphqlPage(variables, offset); // retry transient failures\n  }\n  if (m && m[1].startsWith('4')) console.error(`Glints query rejected (${m[1]}) — likely schema drift; re-capture query from glints.com devtools`);\n  throw e;\n}","preventionTips":["Expect schema drift — the GraphQL schema is reverse-engineered; re-capture the query from glints.com when 4xx errors start","Throttle page size/maxPages and add delays to avoid 429s","Log the error detail (errors[0].message or body prefix) — it names the server-side cause directly","Wrap pagination in retry-with-backoff for 5xx and 429"],"tags":["graphql","http-error","glints","api","rate-limit"],"backgroundTag":"http-error-response","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"}