mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
fix(traffic): say which upstream declined a road load
Street Traffic draws on OpenStreetMap for geometry and TomTom for flow, and the row said "Road data temporarily unavailable" whichever one failed. The reporter of #661 went and verified a TomTom key while every public Overpass mirror was refusing their network with HTTP 406 — a status fetchRoads already had and dropped on the floor. Classify the refusal where the layer talks to Overpass: 429 is "Overpass rate-limited", 504 is "Overpass timed out", anything else is "Overpass refused the road query (HTTP <status>)". The first two are the words alpr's Overpass source already uses; the status is what says which upstream declined, which a single-source layer never has to. The error carries its status as a RoadRequestError, following LiveSourceError in src/sources/live/contract.js, so a caller can branch on the code without parsing English. The catch promotes a classified refusal and keeps the general line for everything else — the branch is on the error type, not on its text, because a dropped socket throws whatever the platform felt like saying and "Failed to fetch" on a panel row helps nobody. Retries, backoff, caching and the mirror rotation are untouched.
This commit is contained in:
1 parent
0dbde1e36c
commit
c24399e99d
6 files changed
+149
-4
No files matched your search
@@ -4,6 +4,7 @@ import {
|
||||
TILE_CACHE_MAX_ENTRIES,
|
||||
FAST_FETCH_ALTITUDE,
|
||||
} from './policy.js';
|
||||
import { RoadRequestError, roadRequestError } from './source.js';
|
||||
|
||||
export function createIngestion({
|
||||
state: layerState,
|
||||
@@ -67,7 +68,7 @@ export function createIngestion({
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Overpass API returned ${response.status}`);
|
||||
throw roadRequestError(response.status);
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
@@ -307,8 +308,16 @@ export function createIngestion({
|
||||
renderedSomething = true;
|
||||
} catch (e) {
|
||||
if (e?.name === 'AbortError') return;
|
||||
if (generation === layerState._loadGeneration && !renderedSomething)
|
||||
layerState._roadError = 'Road data temporarily unavailable';
|
||||
if (generation === layerState._loadGeneration && !renderedSomething) {
|
||||
// A refusal we classified carries its own line; anything else — a
|
||||
// dropped connection, a malformed snapshot — keeps the general one,
|
||||
// because `e.message` from the platform is not a sentence anyone
|
||||
// should have to read off a panel.
|
||||
layerState._roadError =
|
||||
e instanceof RoadRequestError
|
||||
? e.message
|
||||
: 'Road data temporarily unavailable';
|
||||
}
|
||||
console.warn('[Data:Traffic] Fetch error:', e);
|
||||
} finally {
|
||||
if (generation === layerState._loadGeneration) {
|
||||
|
||||
Reference in new issue
Block a user