Fix /place 500s, /day rate-limit handling, calendar listener leak, error surfacing (#40)
- /api/v2/place still called grid.in_north_america(), which the worldwide- coverage change removed — every request raised AttributeError (500). The failure was invisible because compare.js treats the call as best-effort, so the instant chip-naming feature was silently dead. Drop the dead guard; the lat/lon Query validators already bound the inputs. - /api/v2/day was the only data route not wrapping get_history in _weather_fetch_error, so a rate-limited cold cell returned a raw 500 instead of the clean 503 the other routes emit. - calendar: the #calendar pointerleave handler was re-registered inside attachHover on every render — and the comfort slider re-renders per input tick, stacking dozens of copies. Register it once at module scope next to the matching document-level dismiss handler. - getJSON: check res.ok before parsing the body as JSON and fall back to the status line, so a non-JSON error body (a proxy 502 HTML page) reads as "Request failed (502 Bad Gateway)" instead of a JSON parse error.
This commit is contained in:
parent
efd43dcbb5
commit
a3c22ef6d7
2 changed files with 17 additions and 4 deletions
|
|
@ -208,6 +208,14 @@ document.addEventListener("pointerdown", (e) => {
|
|||
}
|
||||
});
|
||||
|
||||
// Mouse only: hovering off the grid hides the preview. On touch the tooltip is
|
||||
// click-activated and must persist until a non-day tap (the handler above).
|
||||
// Registered once — #calendar persists across re-renders (only its cells are
|
||||
// replaced), so registering inside attachHover would stack a copy per render.
|
||||
calEl.addEventListener("pointerleave", (e) => {
|
||||
if (e.pointerType === "mouse") document.getElementById("cal-tip").hidden = true;
|
||||
});
|
||||
|
||||
// ---- location picker ----
|
||||
// The Find button opens the shared modal map picker; choosing a spot loads it.
|
||||
const findBtn = document.getElementById("find-btn");
|
||||
|
|
@ -841,9 +849,6 @@ function attachHover(byDate) {
|
|||
else armedCell = c; // first tap only showed the tooltip
|
||||
});
|
||||
});
|
||||
// Mouse only: hovering off the grid hides the preview. On touch the tooltip is
|
||||
// click-activated and must persist until a non-day tap (see the document handler).
|
||||
calEl.addEventListener("pointerleave", (e) => { if (e.pointerType === "mouse") tip.hidden = true; });
|
||||
}
|
||||
|
||||
// ---- restore (hash from a shared link, else the last place you looked at) ----
|
||||
|
|
|
|||
|
|
@ -213,8 +213,16 @@ async function fetchStore(url, rec) {
|
|||
cachePut({ ...rec, t: Date.now(), day: localDay() });
|
||||
return rec.d;
|
||||
}
|
||||
if (!res.ok) {
|
||||
// Error bodies aren't always JSON (a proxy 502 serves an HTML page) — fall
|
||||
// back to the status line rather than surfacing a JSON parse error.
|
||||
let detail = null;
|
||||
try { detail = (await res.json()).detail; } catch (e) {}
|
||||
const err = new Error(detail || `Request failed (${res.status} ${res.statusText})`.trim());
|
||||
err.status = res.status;
|
||||
throw err;
|
||||
}
|
||||
const d = await res.json();
|
||||
if (!res.ok) { const err = new Error(d.detail || "request failed"); err.status = res.status; throw err; }
|
||||
cachePut({ url, t: Date.now(), day: localDay(), etag: res.headers.get("ETag") || null, d });
|
||||
return d;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue