{"record":{"id":"ca5f5bfd0e7838ae","repo":"koala73/worldmonitor","slug":"wikidata-request-failed","errorCode":null,"errorMessage":"Wikidata request failed","messagePattern":"Wikidata request failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/worldmonitor/intelligence/v1/get-country-facts.ts","lineNumber":178,"sourceCode":"    } catch (error) {\n      if (attempt === WIKIDATA_ATTEMPTS - 1) throw error;\n      continue;\n    }\n    if (!response.ok) {\n      const retryable = response.status === 429 || response.status >= 500;\n      if (retryable && attempt < WIKIDATA_ATTEMPTS - 1) continue;\n      throw new Error(`Wikidata request failed with status ${response.status}`);\n    }\n\n    try {\n      const data = (await response.json()) as WikidataResponse;\n      return data.results?.bindings ?? [];\n    } catch (error) {\n      if (attempt === WIKIDATA_ATTEMPTS - 1) throw error;\n    }\n  }\n\n  throw new Error('Wikidata request failed');\n}\n\nfunction parseWikidataFacts(bindings: WikidataBinding[]): WikiResult | null {\n  if (bindings.length === 0) return null;\n\n  const firstLabel = (field: keyof WikidataBinding): string => {\n    for (const binding of bindings) {\n      const label = cleanLabel(binding[field]?.value);\n      if (label) return label;\n    }\n    return '';\n  };\n  const firstNumber = (field: 'population' | 'area'): number => {\n    for (const binding of bindings) {\n      const value = Number(binding[field]?.value);\n      if (Number.isFinite(value) && value > 0) return value;\n    }\n    return 0;","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/koala73/worldmonitor/blob/9361220cc013571781071f0206e4d80fd14b2f7f/server/worldmonitor/intelligence/v1/get-country-facts.ts#L160-L196","documentation":"This is the exhausted-loop sentinel in queryWikidata: after all WIKIDATA_ATTEMPTS iterations, if no attempt returned bindings (each either failed HTTP and the last attempt rethrew, or JSON parsing failed and the last attempt swallowed/kept looping), the function throws generic Error 'Wikidata request failed'. It indicates the Wikidata lookup could not complete within the retry budget.","triggerScenarios":"Every attempt fails: the last attempt's non-ok status rethrows the status error, or the final attempt's response.json() throws (invalid/truncated body) and control falls out of the loop, reaching this throw.","commonSituations":"Wikidata returning HTML error pages or empty bodies during an outage so JSON parsing fails on every attempt; sustained rate limiting across the whole retry window; network issues truncating responses; retry count too low for a flaky endpoint.","solutions":["Inspect upstream behavior during the incident; check https://www.wikidata.org status and whether responses are HTML error pages rather than JSON","Increase WIKIDATA_ATTEMPTS and add backoff so transient outages fit within the retry budget","Log the underlying parse/HTTP error per attempt so this generic error can be diagnosed","Serve stale cached country facts (or a secondary source) when this error is caught"],"exampleFix":"} catch (error) {\n  if (attempt === WIKIDATA_ATTEMPTS - 1) throw error;\n}\n// after: record why each attempt failed\n} catch (error) {\n  lastError = error;\n  if (attempt === WIKIDATA_ATTEMPTS - 1) throw new Error(`Wikidata request failed: ${String(error)}`);\n}","handlingStrategy":"fallback","validationCode":"// Precheck connectivity/body shape before consuming attempts\nconst probe = await fetch(WIKIDATA_ENDPOINT, { method: 'HEAD' });\nif (!probe.ok) useCachedFacts();","typeGuard":"function isWikidataExhausted(e: unknown): boolean {\n  return e instanceof Error && e.message === 'Wikidata request failed';\n}","tryCatchPattern":"try {\n  facts = await getCountryFacts(cc);\n} catch (e) {\n  if (isWikidataExhausted(e)) return cachedOrEmptyFacts(cc);\n  throw e;\n}","preventionTips":["Instrument each attempt to record whether HTTP or JSON parsing failed","Increase WIKIDATA_ATTEMPTS / add backoff for outage windows","Keep a last-known-good cache of country facts as a fallback source","Alert on repeated exhausted-loop errors — they indicate sustained upstream failure"],"tags":["wikidata","retry-exhausted","json-parse","upstream"],"backgroundTag":"upstream-retries-exhausted","analyzedSha":"9361220cc013571781071f0206e4d80fd14b2f7f","analyzedAt":"2026-09-01T10:32:37.851Z","contentChangedAt":"2026-09-01T10:32:37.851Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}