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

  1. Log/inspect the numeric status: 404 means fix the endpoint URL; 429 means add backoff/spacing; 5xx means retry later
  2. Add retry with exponential backoff for transient 429/5xx responses before failing the whole fetch
  3. Confirm the request URL, query parameters, and Accept header still match the current ECCC API contract
  4. 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

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


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)