koala73/worldmonitor · error · Error
HTTP ${response.status}
Error message
HTTP ${response.status} What it means
Generic non-2xx guard for the ECCC fetch wrapper: after issuing the request (with Accept header, User-Agent, redirect:'error', and an AbortSignal timeout), any response whose `ok` is false raises `HTTP <status>`. It surfaces the raw HTTP status so callers can distinguish 404/429/5xx outcomes of the alert fetch.
Solutions
- Log/inspect the numeric status: 404 means fix the endpoint URL; 429 means add backoff/spacing; 5xx means retry later
- Add retry with exponential backoff for transient 429/5xx responses before failing the whole fetch
- Confirm the request URL, query parameters, and Accept header still match the current ECCC API contract
- Keep a valid descriptive User-Agent (per repo policy) since some upstreams reject requests without one
Example fix
// before
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// after
if (!response.ok) {
if (response.status === 429 || response.status >= 500) {
await sleep(backoffMs);
return fetchWithRetry(url, opts, attempt + 1);
}
throw new Error(`HTTP ${response.status}`);
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try {
const data = await fetchEcccJson(url);
} catch (err) {
const m = /^HTTP (\d+)$/.exec(err.message);
if (m && (m[1] === '429' || m[1].startsWith('5'))) {
await backoffAndRetry();
} else if (m) {
console.error(`Non-retryable ECCC HTTP status ${m[1]}`);
}
} Prevention
- Poll within published rate limits and stagger requests (repo policy: stagger Yahoo-like upstreams)
- Keep User-Agent and Accept headers current with API requirements
- Pin and monitor the endpoint URL for upstream version changes
- Distinguish retryable (429/5xx) from permanent (4xx) statuses before retrying
When it happens
Trigger: The ECCC alerts endpoint (or any URL passed through this fetch helper) responds with a status outside 200-299 — e.g. 404 after a schema/URL change, 429 rate limiting, 500/503 server-side outage.
Common situations: ECCC renames or versions an endpoint; the client is rate-limited for polling too aggressively or missing an acceptable User-Agent; upstream returns 503 during maintenance; a redirect is attempted but redirect:'error' converts it into a 3xx failure surfaced as HTTP 3xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Brief service unavailable (${res.status})
- Wikidata request failed with status ${response.status}
- Redis HTTP ${resp.status}
- HTTP ${response.status}
- ECCC issued and continued fetches both failed: ${detail}
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/d6e455043daecacc.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/_weather-alert-select.mjs:838
allowedHosts,
maxBytes = ECCC_MAX_BYTES,
fetchFn = globalThis.fetch,
userAgent = CHROME_UA,
timeoutMs = 15_000,
accept = 'application/geo+json',
byteBudget,
} = {}) {
const parsed = new URL(url);
const allowed = new Set((allowedHosts || []).map((host) => String(host).toLowerCase()));
if (parsed.protocol !== 'https:' || !allowed.has(parsed.hostname.toLowerCase())) {
throw new Error('UNTRUSTED_SOURCE_HOST');
}
const response = await fetchFn(parsed.toString(), {
headers: { Accept: accept, 'User-Agent': userAgent },
redirect: 'error',
signal: AbortSignal.timeout(timeoutMs),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return readResponseLimited(response, maxBytes, byteBudget);
}
View on GitHub (pinned to 7d06c8633d)