(url: string, init?: RequestInit)
| 3 | |
| 4 | /** Fetch helper that throws on non-OK responses. */ |
| 5 | export async function fetchJson<T>(url: string, init?: RequestInit): Promise<T> { |
| 6 | const res = await fetch(url, init) |
| 7 | if (res.status === 401) { |
| 8 | // Global "session died / never had one" signal. AuthContext listens |
| 9 | // and flips back to the login page. Throw after dispatching so the |
| 10 | // caller's promise rejects rather than silently resolving. |
| 11 | window.dispatchEvent(new CustomEvent('app:unauthorized')) |
| 12 | throw new Error('Unauthorized') |
| 13 | } |
| 14 | if (!res.ok) { |
| 15 | const err = await res.json().catch(() => ({ error: res.statusText })) |
| 16 | throw new Error(err.error || res.statusText) |
| 17 | } |
| 18 | return res.json() |
| 19 | } |
no test coverage detected