Files
fn_registry/frontend/functions/infra/fetch_json.ts
T
egutierrez 8618aa1be3 chore: auto-commit (57 archivos)
- frontend/functions/core/format_datetime_short.md
- frontend/functions/core/format_datetime_short.test.ts
- frontend/functions/core/format_datetime_short.ts
- frontend/functions/core/format_duration.md
- frontend/functions/core/format_duration.test.ts
- frontend/functions/core/format_duration.ts
- frontend/functions/core/month_grid.md
- frontend/functions/core/month_grid.test.ts
- frontend/functions/core/month_grid.ts
- frontend/functions/core/string_hash_palette.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 03:41:58 +02:00

45 lines
1.2 KiB
TypeScript

/**
* HTTPError — error HTTP con status code.
* Lanzado por fetchJSON cuando la respuesta no es ok.
*/
export class HTTPError extends Error {
constructor(public status: number, message: string) {
super(message);
this.name = "HTTPError";
}
}
/**
* fetchJSON — wrapper de fetch que parsea JSON, lanza HTTPError en errores HTTP
* y retorna undefined en 204 No Content.
*
* URL final: `${baseUrl ?? ""}${path}`.
* Headers default: `{ "Content-Type": "application/json" }`, mergeables via init.headers.
* credentials: "include" por defecto, sobreescribible via init.
*/
export async function fetchJSON<T>(
path: string,
init?: RequestInit,
baseUrl?: string,
): Promise<T> {
const res = await fetch(`${baseUrl ?? ""}${path}`, {
credentials: "include",
...init,
headers: {
"Content-Type": "application/json",
...(init?.headers ?? {}),
},
});
if (!res.ok) {
const err = await res.json().catch(() => ({ Message: res.statusText }));
throw new HTTPError(
res.status,
err.Message ?? err.message ?? res.statusText,
);
}
if (res.status === 204) return undefined as T;
return res.json() as Promise<T>;
}