Skip to content

Commit 78e05b5

Browse files
committed
[DEV-21438] Implement global error handler
1 parent e373bf2 commit 78e05b5

File tree

3 files changed

+75
-35
lines changed

3 files changed

+75
-35
lines changed

src/Client.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ import {
3232
Subscriptions,
3333
Templates,
3434
} from './endpoints';
35-
import type { HeadersMap } from './http';
36-
import { createHttpClient } from './http';
35+
import type { ApiError } from './http';
36+
import { createHttpClient, type HeadersMap } from './http';
3737

3838
const DEFAULT_BASE_URL = 'https://api.prezly.com';
3939

@@ -42,6 +42,7 @@ export interface ClientOptions {
4242
baseUrl?: string;
4343
headers?: HeadersMap;
4444
fetch?: Fetch;
45+
onError?: (error: ApiError) => void;
4546
}
4647

4748
export interface Client {
@@ -83,9 +84,10 @@ export function createClient({
8384
baseUrl = DEFAULT_BASE_URL,
8485
headers = {},
8586
fetch,
87+
onError,
8688
}: ClientOptions): Client {
8789
const api = createDeferredJobsApiClient(
88-
createApiClient(createHttpClient({ fetch, baseUrl }), {
90+
createApiClient(createHttpClient({ fetch, baseUrl, onError }), {
8991
accessToken,
9092
headers,
9193
}),

src/http/HttpClient.ts

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Fetch } from '../api';
22

3+
import type { ApiError } from './ApiError';
34
import { createRequest } from './createRequest';
45
import type { ApiResponse, Params, ParamsWithPayload } from './types';
56
import { Method } from './types';
@@ -12,9 +13,16 @@ export interface HttpClient {
1213
delete<V = any>(url: string, params?: ParamsWithPayload): Promise<ApiResponse<V>>;
1314
}
1415

15-
export function createHttpClient(options: { baseUrl?: string; fetch?: Fetch } = {}): HttpClient {
16+
interface Options {
17+
baseUrl?: string;
18+
fetch?: Fetch;
19+
onError?: (error: ApiError) => void;
20+
}
21+
22+
export function createHttpClient(options: Options = {}): HttpClient {
1623
const baseUrl = options.baseUrl ?? null;
1724
const fetchImpl = options.fetch ?? fetch;
25+
const onError = options.onError;
1826

1927
function resolveUrl(url: string) {
2028
if (baseUrl) {
@@ -25,47 +33,72 @@ export function createHttpClient(options: { baseUrl?: string; fetch?: Fetch } =
2533

2634
return {
2735
get(url, { headers, query } = {}) {
28-
return createRequest(fetchImpl, resolveUrl(url), {
29-
headers,
30-
method: Method.GET,
31-
query,
32-
});
36+
return createRequest(
37+
fetchImpl,
38+
resolveUrl(url),
39+
{
40+
headers,
41+
method: Method.GET,
42+
query,
43+
},
44+
onError,
45+
);
3346
},
3447

3548
post(url: string, { headers, payload, query } = {}) {
36-
return createRequest(fetchImpl, resolveUrl(url), {
37-
headers,
38-
method: Method.POST,
39-
payload,
40-
query,
41-
});
49+
return createRequest(
50+
fetchImpl,
51+
resolveUrl(url),
52+
{
53+
headers,
54+
method: Method.POST,
55+
payload,
56+
query,
57+
},
58+
onError,
59+
);
4260
},
4361

4462
put(url, { headers, payload, query } = {}) {
45-
return createRequest(fetchImpl, resolveUrl(url), {
46-
headers,
47-
method: Method.PUT,
48-
payload,
49-
query,
50-
});
63+
return createRequest(
64+
fetchImpl,
65+
resolveUrl(url),
66+
{
67+
headers,
68+
method: Method.PUT,
69+
payload,
70+
query,
71+
},
72+
onError,
73+
);
5174
},
5275

5376
patch(url: string, { headers, payload, query } = {}) {
54-
return createRequest(fetchImpl, resolveUrl(url), {
55-
headers,
56-
method: Method.PATCH,
57-
payload,
58-
query,
59-
});
77+
return createRequest(
78+
fetchImpl,
79+
resolveUrl(url),
80+
{
81+
headers,
82+
method: Method.PATCH,
83+
payload,
84+
query,
85+
},
86+
onError,
87+
);
6088
},
6189

6290
delete(url: string, { headers, payload, query } = {}) {
63-
return createRequest(fetchImpl, resolveUrl(url), {
64-
headers,
65-
method: Method.DELETE,
66-
payload,
67-
query,
68-
});
91+
return createRequest(
92+
fetchImpl,
93+
resolveUrl(url),
94+
{
95+
headers,
96+
method: Method.DELETE,
97+
payload,
98+
query,
99+
},
100+
onError,
101+
);
69102
},
70103
};
71104
}

src/http/createRequest.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
NETWORK_PROBLEM_ERROR_MESSAGE,
88
} from './constants';
99
import { createUrlWithQuery } from './lib';
10-
import type { Method, HeadersMap, ApiResponse } from './types';
10+
import type { ApiResponse, HeadersMap, Method } from './types';
1111
import { HttpCodes } from './types';
1212

1313
function extractHeaders(headers: Headers): HeadersMap {
@@ -59,6 +59,7 @@ export async function createRequest<P = any>(
5959
payload?: object;
6060
query?: object;
6161
},
62+
onError?: (error: ApiError) => void,
6263
): Promise<ApiResponse<P>> {
6364
const { headers, method, payload, query } = options;
6465
try {
@@ -91,10 +92,14 @@ export async function createRequest<P = any>(
9192
responsePayload = createFakeErrorPayload(response);
9293
}
9394

94-
throw new ApiError({
95+
const error = new ApiError({
9596
payload: responsePayload,
9697
...extractResponse(response),
9798
});
99+
100+
onError?.(error);
101+
102+
throw error;
98103
}
99104

100105
const responsePayload =

0 commit comments

Comments
 (0)