fetch.ts (1239B)
1 export type HttpFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>; 2 3 export type FetchJsonErrorKind = "http" | "network" | "parse"; 4 5 export type FetchJsonError = { 6 ok: false; 7 kind: FetchJsonErrorKind; 8 url: string; 9 message: string; 10 status?: number; 11 status_text?: string; 12 }; 13 14 export type FetchJsonResult<T> = { ok: true; data: T } | FetchJsonError; 15 16 export async function fetch_json<T>(fetch_fn: HttpFetch, url: string): Promise<FetchJsonResult<T>> { 17 let res: Response; 18 try { 19 res = await fetch_fn(url); 20 } catch (error) { 21 const message = error instanceof Error ? error.message : "network_error"; 22 return { ok: false, kind: "network", url, message }; 23 } 24 25 if (!res.ok) { 26 return { 27 ok: false, 28 kind: "http", 29 url, 30 message: res.statusText || "http_error", 31 status: res.status, 32 status_text: res.statusText 33 }; 34 } 35 36 try { 37 const data: T = await res.json(); 38 return { ok: true, data }; 39 } catch (error) { 40 const message = error instanceof Error ? error.message : "parse_error"; 41 return { ok: false, kind: "parse", url, message }; 42 } 43 }