export default async function fetchJson( input: RequestInfo, init?: RequestInit ): Promise { const response = await fetch(input, { ...init, credentials: 'include' }); // if the server replies, there's always some data in json // if there's a network error, it will throw at the previous line const data = await response.json(); // response.ok is true when res.status is 2xx // https://developer.mozilla.org/en-US/docs/Web/API/Response/ok if (response.ok) { return data; } throw new FetchError({ message: response.statusText, response, data, }); } export async function publishJSON( input: RequestInfo, method: string = 'POST', body?: Object, init?: RequestInit ) { return fetchJson(input, { ...init, method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(body), }); } export class FetchError extends Error { response: Response; data: { message: string; }; constructor({ message, response, data, }: { message: string; response: Response; data: { message: string; }; }) { // Pass remaining arguments (including vendor specific ones) to parent constructor super(message); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, FetchError); } this.name = 'FetchError'; this.response = response; this.data = data ?? { message: message }; } }