diff --git a/frontend/src/lib/document/timeline.spec.ts b/frontend/src/lib/document/timeline.spec.ts index 212437a5..9deca472 100644 --- a/frontend/src/lib/document/timeline.spec.ts +++ b/frontend/src/lib/document/timeline.spec.ts @@ -285,6 +285,29 @@ describe('fetchDensity', () => { expect(result).toEqual({ density: [], minDate: null, maxDate: null }); }); + + it('emits console.warn with the status when the response is non-ok', async () => { + const fetch = vi.fn().mockResolvedValue({ ok: false, status: 503 }); + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}); + + await fetchDensity(fetch, null, true); + + expect(warn).toHaveBeenCalledTimes(1); + expect(warn.mock.calls[0][0]).toContain('503'); + warn.mockRestore(); + }); + + it('emits console.warn with the caught error when fetch rejects', async () => { + const error = new TypeError('Network down'); + const fetch = vi.fn().mockRejectedValue(error); + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}); + + await fetchDensity(fetch, null, true); + + expect(warn).toHaveBeenCalledTimes(1); + expect(warn.mock.calls[0]).toContain(error); + warn.mockRestore(); + }); }); describe('tickIndicesFor', () => { diff --git a/frontend/src/lib/document/timeline.ts b/frontend/src/lib/document/timeline.ts index 5919faf7..81d5c90e 100644 --- a/frontend/src/lib/document/timeline.ts +++ b/frontend/src/lib/document/timeline.ts @@ -208,14 +208,18 @@ export async function fetchDensity( try { const response = await fetch(buildDensityUrl(filters)); - if (!response.ok) return EMPTY; + if (!response.ok) { + console.warn(`[timeline] density fetch responded with ${response.status}`); + return EMPTY; + } const body = (await response.json()) as DocumentDensityResult; return { density: body.buckets, minDate: body.minDate ?? null, maxDate: body.maxDate ?? null }; - } catch { + } catch (error) { + console.warn('[timeline] density fetch failed', error); return EMPTY; } }