47 lines
1.3 KiB
JavaScript
47 lines
1.3 KiB
JavaScript
/*
|
|
* API communication module. Centralizes fetch calls so network details stay
|
|
* out of rendering and state logic. All JSON traffic from the frontend goes
|
|
* through `fetchJson()`, which prepends the versioned base path and unwraps
|
|
* structured error responses into regular thrown errors.
|
|
*/
|
|
|
|
import { API_BASE } from './constants.js';
|
|
|
|
/*
|
|
* Generic JSON fetcher. Prepends the API base path when the caller passes a
|
|
* relative path, forwards headers, and parses the response body on success.
|
|
* Non-2xx responses raise an `Error` whose message is the server's `message`
|
|
* field when present, otherwise a generic status-code fallback.
|
|
*/
|
|
export async function fetchJson(path, options = {}) {
|
|
const url = path.startsWith('http') ? path : `${API_BASE}${path}`;
|
|
|
|
const requestOptions = {
|
|
...options,
|
|
headers: {
|
|
Accept: 'application/json',
|
|
...(options.headers || {})
|
|
}
|
|
};
|
|
|
|
const response = await fetch(url, requestOptions);
|
|
|
|
if (!response.ok) {
|
|
let message = `Request failed for ${url}: ${response.status}`;
|
|
|
|
try {
|
|
const errorPayload = await response.json();
|
|
|
|
if (errorPayload?.message) {
|
|
message = errorPayload.message;
|
|
}
|
|
} catch {
|
|
/* Ignore JSON parse errors for non-JSON responses. */
|
|
}
|
|
|
|
throw new Error(message);
|
|
}
|
|
|
|
return response.json();
|
|
}
|