2024-07-10 14:20:26 +00:00
|
|
|
import {
|
|
|
|
getNetworkErrorMessage,
|
|
|
|
getNetworkErrorDescription,
|
|
|
|
} from "@keycloak/keycloak-ui-shared";
|
2023-01-16 10:23:07 +00:00
|
|
|
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
|
|
|
|
|
2024-07-10 14:20:26 +00:00
|
|
|
export class ApiError extends Error {
|
|
|
|
description?: string;
|
|
|
|
|
|
|
|
constructor(message: string, description?: string) {
|
|
|
|
super(message);
|
|
|
|
this.description = description;
|
|
|
|
}
|
|
|
|
}
|
2023-01-16 10:23:07 +00:00
|
|
|
|
|
|
|
export async function parseResponse<T>(response: Response): Promise<T> {
|
|
|
|
const contentType = response.headers.get(CONTENT_TYPE_HEADER);
|
|
|
|
const isJSON = contentType ? contentType.includes(CONTENT_TYPE_JSON) : false;
|
|
|
|
|
|
|
|
if (!isJSON) {
|
|
|
|
throw new Error(
|
2023-07-11 14:03:21 +00:00
|
|
|
`Expected response to have a JSON content type, got '${contentType}' instead.`,
|
2023-01-16 10:23:07 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await parseJSON(response);
|
|
|
|
|
|
|
|
if (!response.ok) {
|
2024-07-10 14:20:26 +00:00
|
|
|
const message = getNetworkErrorMessage(data);
|
|
|
|
const description = getNetworkErrorDescription(data);
|
|
|
|
|
|
|
|
if (!message) {
|
|
|
|
throw new Error(
|
|
|
|
"Unable to retrieve error message from response, no matching key found.",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new ApiError(message, description);
|
2023-01-16 10:23:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return data as T;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function parseJSON(response: Response): Promise<unknown> {
|
|
|
|
try {
|
|
|
|
return await response.json();
|
|
|
|
} catch (error) {
|
|
|
|
throw new Error("Unable to parse response as valid JSON.", {
|
|
|
|
cause: error,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|