Skip to content
20 changes: 16 additions & 4 deletions src/lib/api/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ const jqHeader = 'X-jq';
const contentTypeHeader = 'Content-Type';

// fetchApiServer is a wrapper around fetch that adds the necessary headers for the Crate API or the MCP API server.
export const parseJsonOrText = async (res: Response): Promise<unknown> => {
try {
return await res.json();
} catch {
try {
return await res.text();
} catch {
return '';
}
}
};

export const fetchApiServer = async (
path: string,
config: ApiConfig,
Expand Down Expand Up @@ -53,7 +65,7 @@ export const fetchApiServer = async (
window.location.replace(`/api/auth/onboarding/login?redirectTo=${encodeURIComponent(getRedirectSuffix())}`);
}
const error = new APIError('An error occurred while fetching the data.', res.status);
error.info = await res.json();
error.info = await parseJsonOrText(res);
throw error;
}

Expand All @@ -68,8 +80,8 @@ export const fetchApiServerJson = async <T>(
body?: BodyInit,
): Promise<T> => {
const res = await fetchApiServer(path, config, jq, httpMethod, body);

return await res.json();
const data = await parseJsonOrText(res);
return data as T;
};

// request is of [path, config, jq]
Expand All @@ -79,7 +91,7 @@ export const fetchApiServerJsonMultiple = (requests: [string | null, ApiConfig,
.filter((r) => r[0] !== null)
.map(([path, config, jq]) =>
// @ts-expect-error path is not null
fetchApiServer(path, config, jq).then((res) => res.json()),
fetchApiServer(path, config, jq).then((res) => parseJsonOrText(res)),
),
);
};
Loading