diff --git a/src/Client.ts b/src/Client.ts index 95ea0616..80a1023b 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -32,8 +32,8 @@ import { Subscriptions, Templates, } from './endpoints'; -import type { HeadersMap } from './http'; -import { createHttpClient } from './http'; +import type { ApiError } from './http'; +import { createHttpClient, type HeadersMap } from './http'; const DEFAULT_BASE_URL = 'https://api.prezly.com'; @@ -42,6 +42,7 @@ export interface ClientOptions { baseUrl?: string; headers?: HeadersMap; fetch?: Fetch; + onError?: (error: ApiError) => void; } export interface Client { @@ -83,9 +84,10 @@ export function createClient({ baseUrl = DEFAULT_BASE_URL, headers = {}, fetch, + onError, }: ClientOptions): Client { const api = createDeferredJobsApiClient( - createApiClient(createHttpClient({ fetch, baseUrl }), { + createApiClient(createHttpClient({ fetch, baseUrl, onError }), { accessToken, headers, }), diff --git a/src/http/HttpClient.ts b/src/http/HttpClient.ts index 62a03266..2dc6956b 100644 --- a/src/http/HttpClient.ts +++ b/src/http/HttpClient.ts @@ -1,5 +1,6 @@ import type { Fetch } from '../api'; +import type { ApiError } from './ApiError'; import { createRequest } from './createRequest'; import type { ApiResponse, Params, ParamsWithPayload } from './types'; import { Method } from './types'; @@ -12,9 +13,16 @@ export interface HttpClient { delete(url: string, params?: ParamsWithPayload): Promise>; } -export function createHttpClient(options: { baseUrl?: string; fetch?: Fetch } = {}): HttpClient { +interface Options { + baseUrl?: string; + fetch?: Fetch; + onError?: (error: ApiError) => void; +} + +export function createHttpClient(options: Options = {}): HttpClient { const baseUrl = options.baseUrl ?? null; const fetchImpl = options.fetch ?? fetch; + const onError = options.onError; function resolveUrl(url: string) { if (baseUrl) { @@ -25,47 +33,72 @@ export function createHttpClient(options: { baseUrl?: string; fetch?: Fetch } = return { get(url, { headers, query } = {}) { - return createRequest(fetchImpl, resolveUrl(url), { - headers, - method: Method.GET, - query, - }); + return createRequest( + fetchImpl, + resolveUrl(url), + { + headers, + method: Method.GET, + query, + }, + onError, + ); }, post(url: string, { headers, payload, query } = {}) { - return createRequest(fetchImpl, resolveUrl(url), { - headers, - method: Method.POST, - payload, - query, - }); + return createRequest( + fetchImpl, + resolveUrl(url), + { + headers, + method: Method.POST, + payload, + query, + }, + onError, + ); }, put(url, { headers, payload, query } = {}) { - return createRequest(fetchImpl, resolveUrl(url), { - headers, - method: Method.PUT, - payload, - query, - }); + return createRequest( + fetchImpl, + resolveUrl(url), + { + headers, + method: Method.PUT, + payload, + query, + }, + onError, + ); }, patch(url: string, { headers, payload, query } = {}) { - return createRequest(fetchImpl, resolveUrl(url), { - headers, - method: Method.PATCH, - payload, - query, - }); + return createRequest( + fetchImpl, + resolveUrl(url), + { + headers, + method: Method.PATCH, + payload, + query, + }, + onError, + ); }, delete(url: string, { headers, payload, query } = {}) { - return createRequest(fetchImpl, resolveUrl(url), { - headers, - method: Method.DELETE, - payload, - query, - }); + return createRequest( + fetchImpl, + resolveUrl(url), + { + headers, + method: Method.DELETE, + payload, + query, + }, + onError, + ); }, }; } diff --git a/src/http/createRequest.ts b/src/http/createRequest.ts index 675fc252..18f751f8 100644 --- a/src/http/createRequest.ts +++ b/src/http/createRequest.ts @@ -7,7 +7,7 @@ import { NETWORK_PROBLEM_ERROR_MESSAGE, } from './constants'; import { createUrlWithQuery } from './lib'; -import type { Method, HeadersMap, ApiResponse } from './types'; +import type { ApiResponse, HeadersMap, Method } from './types'; import { HttpCodes } from './types'; function extractHeaders(headers: Headers): HeadersMap { @@ -59,6 +59,7 @@ export async function createRequest

( payload?: object; query?: object; }, + onError?: (error: ApiError) => void, ): Promise> { const { headers, method, payload, query } = options; try { @@ -91,10 +92,14 @@ export async function createRequest

( responsePayload = createFakeErrorPayload(response); } - throw new ApiError({ + const error = new ApiError({ payload: responsePayload, ...extractResponse(response), }); + + onError?.(error); + + throw error; } const responsePayload =