1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-17 21:26:13 -04:00
Files
Sonarr/frontend/src/Utilities/Fetch/fetchJson.ts
Mark McDowall ae201f5299 Use react-query for queue UI
New: Season packs and multi-episode releases will show as a single item in the queue
Closes #6537
2025-09-01 15:08:19 -07:00

92 lines
2.0 KiB
TypeScript

import anySignal from './anySignal';
export class ApiError extends Error {
public statusCode: number;
public statusText: string;
public statusBody?: ApiErrorResponse;
public constructor(
path: string,
statusCode: number,
statusText: string,
statusBody?: ApiErrorResponse
) {
super(`Request Error: (${statusCode}) ${path}`);
this.statusCode = statusCode;
this.statusText = statusText;
this.statusBody = statusBody;
Object.setPrototypeOf(this, new.target.prototype);
}
}
export interface ApiErrorResponse {
message: string;
details: string;
}
export interface FetchJsonOptions<TData> extends Omit<RequestInit, 'body'> {
path: string;
headers?: HeadersInit;
body?: TData;
timeout?: number;
}
export const urlBase = window.Sonarr.urlBase;
export const apiRoot = '/api/v5'; // window.Sonarr.apiRoot;
async function fetchJson<T, TData>({
body,
path,
signal,
timeout,
...options
}: FetchJsonOptions<TData>): Promise<T> {
const abortController = new AbortController();
let timeoutID: ReturnType<typeof setTimeout> | null = null;
if (timeout) {
timeoutID = setTimeout(() => {
abortController.abort();
}, timeout);
}
const response = await fetch(path, {
...options,
body: body ? JSON.stringify(body) : undefined,
headers: {
...options.headers,
Accept: 'application/json',
'Content-Type': 'application/json',
},
signal: anySignal(abortController.signal, signal),
});
if (timeoutID) {
clearTimeout(timeoutID);
}
if (!response.ok) {
// eslint-disable-next-line init-declarations
let body;
try {
body = (await response.json()) as ApiErrorResponse;
} catch {
throw new ApiError(path, response.status, response.statusText);
}
throw new ApiError(path, response.status, response.statusText, body);
}
if (response.status === 204) {
return {} as T;
}
return response.json() as T;
}
export default fetchJson;