@unito/integration-sdk 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -953,22 +953,46 @@ class Integration {
953
953
  * Defines methods for the following HTTP methods: GET, POST, PUT, PATCH, DELETE.
954
954
  *
955
955
  * Needs to be initialized with a prepareRequest function to define the Provider's base URL and any specific headers to
956
- * add to the requests, and can also be configured to use a provided rate limiting function.
956
+ * add to the requests, can also be configured to use a provided rate limiting function, and custom error handler.
957
+ *
958
+ * Multiple `Provider` instances can be created, with different configurations to call different providers APIs with
959
+ * different rateLimiting functions, as needed.
957
960
  * @see {@link RateLimiter}
958
961
  * @see {@link prepareRequest}
962
+ * @see {@link customErrorHandler}
959
963
  */
960
964
  class Provider {
965
+ /**
966
+ * The Rate Limiter function to use to limit the rate of calls made to the provider based on the caller's credentials.
967
+ */
961
968
  rateLimiter = undefined;
969
+ /**
970
+ * Function called before each request to define the Provider's base URL and any specific headers to add to the requests.
971
+ *
972
+ * This is applied at large to all requests made to the provider. If you need to add specific headers to a single request,
973
+ * pass it through the RequestOptions object when calling the Provider's methods.
974
+ */
962
975
  prepareRequest;
976
+ /**
977
+ * (Optional) Custom error handler to handle specific errors returned by the provider.
978
+ *
979
+ * If provided, this method should only care about custom errors returned by the provider and return the corresponding
980
+ * HttpError from the SDK. If the error encountered is a standard error, it should return undefined and let the SDK handle it.
981
+ *
982
+ * @see buildHttpError for the list of standard errors the SDK can handle.
983
+ */
984
+ customErrorHandler;
963
985
  /**
964
986
  * Initializes a Provider with the given options.
965
987
  *
966
988
  * @property prepareRequest - function to define the Provider's base URL and specific headers to add to the request.
967
989
  * @property rateLimiter - function to limit the rate of calls to the provider based on the caller's credentials.
990
+ * @property customErrorHandler - function to handle specific errors returned by the provider.
968
991
  */
969
992
  constructor(options) {
970
993
  this.prepareRequest = options.prepareRequest;
971
994
  this.rateLimiter = options.rateLimiter;
995
+ this.customErrorHandler = options.customErrorHandler;
972
996
  }
973
997
  /**
974
998
  * Performs a GET request to the provider.
@@ -1132,16 +1156,16 @@ class Provider {
1132
1156
  if (error instanceof Error) {
1133
1157
  switch (error.name) {
1134
1158
  case 'AbortError':
1135
- throw buildHttpError(408, 'Request aborted');
1159
+ throw this.handleError(408, 'Request aborted');
1136
1160
  case 'TimeoutError':
1137
- throw buildHttpError(408, 'Request timeout');
1161
+ throw this.handleError(408, 'Request timeout');
1138
1162
  }
1139
1163
  }
1140
- throw buildHttpError(500, `Unexpected error while calling the provider: "${error}"`);
1164
+ throw this.handleError(500, `Unexpected error while calling the provider: "${error}"`);
1141
1165
  }
1142
1166
  if (response.status >= 400) {
1143
1167
  const textResult = await response.text();
1144
- throw buildHttpError(response.status, textResult);
1168
+ throw this.handleError(response.status, textResult);
1145
1169
  }
1146
1170
  const responseContentType = response.headers.get('content-type');
1147
1171
  let body;
@@ -1150,13 +1174,13 @@ class Provider {
1150
1174
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
1151
1175
  // Default to application/json if no Content-Type header is provided
1152
1176
  if (responseContentType && !responseContentType.includes('application/json')) {
1153
- throw buildHttpError(500, `Unsupported content-type. Expected 'application/json', got '${responseContentType}'`);
1177
+ throw this.handleError(500, `Unsupported content-type. Expected 'application/json', got '${responseContentType}'`);
1154
1178
  }
1155
1179
  try {
1156
1180
  body = response.body ? await response.json() : undefined;
1157
1181
  }
1158
1182
  catch (err) {
1159
- throw buildHttpError(500, `Invalid JSON response`);
1183
+ throw this.handleError(500, `Invalid JSON response`);
1160
1184
  }
1161
1185
  }
1162
1186
  else if (headers.Accept == 'application/octet-stream') {
@@ -1164,12 +1188,16 @@ class Provider {
1164
1188
  body = response.body;
1165
1189
  }
1166
1190
  else {
1167
- throw buildHttpError(500, 'Unsupported accept header');
1191
+ throw this.handleError(500, 'Unsupported accept header');
1168
1192
  }
1169
1193
  return { status: response.status, headers: response.headers, body };
1170
1194
  };
1171
1195
  return this.rateLimiter ? this.rateLimiter(options, callToProvider) : callToProvider();
1172
1196
  }
1197
+ handleError(responseStatus, message) {
1198
+ const customError = this.customErrorHandler?.(responseStatus, message);
1199
+ return customError ?? buildHttpError(responseStatus, message);
1200
+ }
1173
1201
  }
1174
1202
 
1175
1203
  /**
@@ -1,3 +1,4 @@
1
+ import * as HttpErrors from '../httpErrors.js';
1
2
  import { Credentials } from '../middlewares/credentials.js';
2
3
  import Logger from '../resources/logger.js';
3
4
  /**
@@ -58,12 +59,25 @@ export type Response<T> = {
58
59
  * Defines methods for the following HTTP methods: GET, POST, PUT, PATCH, DELETE.
59
60
  *
60
61
  * Needs to be initialized with a prepareRequest function to define the Provider's base URL and any specific headers to
61
- * add to the requests, and can also be configured to use a provided rate limiting function.
62
+ * add to the requests, can also be configured to use a provided rate limiting function, and custom error handler.
63
+ *
64
+ * Multiple `Provider` instances can be created, with different configurations to call different providers APIs with
65
+ * different rateLimiting functions, as needed.
62
66
  * @see {@link RateLimiter}
63
67
  * @see {@link prepareRequest}
68
+ * @see {@link customErrorHandler}
64
69
  */
65
70
  export declare class Provider {
71
+ /**
72
+ * The Rate Limiter function to use to limit the rate of calls made to the provider based on the caller's credentials.
73
+ */
66
74
  protected rateLimiter: RateLimiter | undefined;
75
+ /**
76
+ * Function called before each request to define the Provider's base URL and any specific headers to add to the requests.
77
+ *
78
+ * This is applied at large to all requests made to the provider. If you need to add specific headers to a single request,
79
+ * pass it through the RequestOptions object when calling the Provider's methods.
80
+ */
67
81
  protected prepareRequest: (options: {
68
82
  credentials: Credentials;
69
83
  logger: Logger;
@@ -71,15 +85,26 @@ export declare class Provider {
71
85
  url: string;
72
86
  headers: Record<string, string>;
73
87
  };
88
+ /**
89
+ * (Optional) Custom error handler to handle specific errors returned by the provider.
90
+ *
91
+ * If provided, this method should only care about custom errors returned by the provider and return the corresponding
92
+ * HttpError from the SDK. If the error encountered is a standard error, it should return undefined and let the SDK handle it.
93
+ *
94
+ * @see buildHttpError for the list of standard errors the SDK can handle.
95
+ */
96
+ protected customErrorHandler: ((responseStatus: number, message: string) => HttpErrors.HttpError | undefined) | undefined;
74
97
  /**
75
98
  * Initializes a Provider with the given options.
76
99
  *
77
100
  * @property prepareRequest - function to define the Provider's base URL and specific headers to add to the request.
78
101
  * @property rateLimiter - function to limit the rate of calls to the provider based on the caller's credentials.
102
+ * @property customErrorHandler - function to handle specific errors returned by the provider.
79
103
  */
80
104
  constructor(options: {
81
105
  prepareRequest: typeof Provider.prototype.prepareRequest;
82
- rateLimiter?: RateLimiter;
106
+ rateLimiter?: RateLimiter | undefined;
107
+ customErrorHandler?: typeof Provider.prototype.customErrorHandler;
83
108
  });
84
109
  /**
85
110
  * Performs a GET request to the provider.
@@ -157,4 +182,5 @@ export declare class Provider {
157
182
  */
158
183
  delete<T = undefined>(endpoint: string, options: RequestOptions): Promise<Response<T>>;
159
184
  private fetchWrapper;
185
+ private handleError;
160
186
  }
@@ -5,22 +5,46 @@ import { buildHttpError } from '../errors.js';
5
5
  * Defines methods for the following HTTP methods: GET, POST, PUT, PATCH, DELETE.
6
6
  *
7
7
  * Needs to be initialized with a prepareRequest function to define the Provider's base URL and any specific headers to
8
- * add to the requests, and can also be configured to use a provided rate limiting function.
8
+ * add to the requests, can also be configured to use a provided rate limiting function, and custom error handler.
9
+ *
10
+ * Multiple `Provider` instances can be created, with different configurations to call different providers APIs with
11
+ * different rateLimiting functions, as needed.
9
12
  * @see {@link RateLimiter}
10
13
  * @see {@link prepareRequest}
14
+ * @see {@link customErrorHandler}
11
15
  */
12
16
  export class Provider {
17
+ /**
18
+ * The Rate Limiter function to use to limit the rate of calls made to the provider based on the caller's credentials.
19
+ */
13
20
  rateLimiter = undefined;
21
+ /**
22
+ * Function called before each request to define the Provider's base URL and any specific headers to add to the requests.
23
+ *
24
+ * This is applied at large to all requests made to the provider. If you need to add specific headers to a single request,
25
+ * pass it through the RequestOptions object when calling the Provider's methods.
26
+ */
14
27
  prepareRequest;
28
+ /**
29
+ * (Optional) Custom error handler to handle specific errors returned by the provider.
30
+ *
31
+ * If provided, this method should only care about custom errors returned by the provider and return the corresponding
32
+ * HttpError from the SDK. If the error encountered is a standard error, it should return undefined and let the SDK handle it.
33
+ *
34
+ * @see buildHttpError for the list of standard errors the SDK can handle.
35
+ */
36
+ customErrorHandler;
15
37
  /**
16
38
  * Initializes a Provider with the given options.
17
39
  *
18
40
  * @property prepareRequest - function to define the Provider's base URL and specific headers to add to the request.
19
41
  * @property rateLimiter - function to limit the rate of calls to the provider based on the caller's credentials.
42
+ * @property customErrorHandler - function to handle specific errors returned by the provider.
20
43
  */
21
44
  constructor(options) {
22
45
  this.prepareRequest = options.prepareRequest;
23
46
  this.rateLimiter = options.rateLimiter;
47
+ this.customErrorHandler = options.customErrorHandler;
24
48
  }
25
49
  /**
26
50
  * Performs a GET request to the provider.
@@ -184,16 +208,16 @@ export class Provider {
184
208
  if (error instanceof Error) {
185
209
  switch (error.name) {
186
210
  case 'AbortError':
187
- throw buildHttpError(408, 'Request aborted');
211
+ throw this.handleError(408, 'Request aborted');
188
212
  case 'TimeoutError':
189
- throw buildHttpError(408, 'Request timeout');
213
+ throw this.handleError(408, 'Request timeout');
190
214
  }
191
215
  }
192
- throw buildHttpError(500, `Unexpected error while calling the provider: "${error}"`);
216
+ throw this.handleError(500, `Unexpected error while calling the provider: "${error}"`);
193
217
  }
194
218
  if (response.status >= 400) {
195
219
  const textResult = await response.text();
196
- throw buildHttpError(response.status, textResult);
220
+ throw this.handleError(response.status, textResult);
197
221
  }
198
222
  const responseContentType = response.headers.get('content-type');
199
223
  let body;
@@ -202,13 +226,13 @@ export class Provider {
202
226
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
203
227
  // Default to application/json if no Content-Type header is provided
204
228
  if (responseContentType && !responseContentType.includes('application/json')) {
205
- throw buildHttpError(500, `Unsupported content-type. Expected 'application/json', got '${responseContentType}'`);
229
+ throw this.handleError(500, `Unsupported content-type. Expected 'application/json', got '${responseContentType}'`);
206
230
  }
207
231
  try {
208
232
  body = response.body ? await response.json() : undefined;
209
233
  }
210
234
  catch (err) {
211
- throw buildHttpError(500, `Invalid JSON response`);
235
+ throw this.handleError(500, `Invalid JSON response`);
212
236
  }
213
237
  }
214
238
  else if (headers.Accept == 'application/octet-stream') {
@@ -216,10 +240,14 @@ export class Provider {
216
240
  body = response.body;
217
241
  }
218
242
  else {
219
- throw buildHttpError(500, 'Unsupported accept header');
243
+ throw this.handleError(500, 'Unsupported accept header');
220
244
  }
221
245
  return { status: response.status, headers: response.headers, body };
222
246
  };
223
247
  return this.rateLimiter ? this.rateLimiter(options, callToProvider) : callToProvider();
224
248
  }
249
+ handleError(responseStatus, message) {
250
+ const customError = this.customErrorHandler?.(responseStatus, message);
251
+ return customError ?? buildHttpError(responseStatus, message);
252
+ }
225
253
  }
@@ -249,6 +249,78 @@ describe('Provider', () => {
249
249
  ]);
250
250
  assert.deepEqual(actualResponse, { status: 204, headers: response.headers, body: undefined });
251
251
  });
252
+ it('uses custom error handler if provided', async (context) => {
253
+ const rateLimitedProvider = new Provider({
254
+ prepareRequest: requestOptions => {
255
+ return {
256
+ url: `www.${requestOptions.credentials.domain ?? 'myApi.com'}`,
257
+ headers: {
258
+ 'X-Custom-Provider-Header': 'value',
259
+ 'X-Provider-Credential-Header': requestOptions.credentials.apiKey,
260
+ },
261
+ };
262
+ },
263
+ rateLimiter: undefined,
264
+ // Change from normal behavior 400 -> 429
265
+ customErrorHandler: (responseStatus) => responseStatus === 400 ? new HttpErrors.RateLimitExceededError('Weird provider behavior') : undefined,
266
+ });
267
+ const response = new Response(undefined, {
268
+ status: 400,
269
+ headers: { 'Content-Type': 'application/json' },
270
+ });
271
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
272
+ const options = {
273
+ credentials: { apiKey: 'apikey#1111' },
274
+ logger: logger,
275
+ signal: new AbortController().signal,
276
+ additionnalheaders: { 'X-Additional-Header': 'value1' },
277
+ };
278
+ let error;
279
+ try {
280
+ await rateLimitedProvider.delete('/endpoint/123', options);
281
+ }
282
+ catch (e) {
283
+ error = e;
284
+ }
285
+ assert.ok(error instanceof HttpErrors.HttpError);
286
+ assert.equal(error.message, 'Weird provider behavior');
287
+ });
288
+ it('uses default behavior if custom error handler returns undefined', async (context) => {
289
+ const rateLimitedProvider = new Provider({
290
+ prepareRequest: requestOptions => {
291
+ return {
292
+ url: `www.${requestOptions.credentials.domain ?? 'myApi.com'}`,
293
+ headers: {
294
+ 'X-Custom-Provider-Header': 'value',
295
+ 'X-Provider-Credential-Header': requestOptions.credentials.apiKey,
296
+ },
297
+ };
298
+ },
299
+ rateLimiter: undefined,
300
+ // Custom Error Handler returning undefined (default behavior should apply)
301
+ customErrorHandler: () => undefined,
302
+ });
303
+ const response = new Response(undefined, {
304
+ status: 404,
305
+ headers: { 'Content-Type': 'application/json' },
306
+ });
307
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
308
+ const options = {
309
+ credentials: { apiKey: 'apikey#1111' },
310
+ logger: logger,
311
+ signal: new AbortController().signal,
312
+ additionnalheaders: { 'X-Additional-Header': 'value1' },
313
+ };
314
+ let error;
315
+ try {
316
+ await rateLimitedProvider.delete('/endpoint/123', options);
317
+ }
318
+ catch (e) {
319
+ error = e;
320
+ }
321
+ assert.ok(error instanceof HttpErrors.HttpError);
322
+ assert.equal(error.message, 'Not found');
323
+ });
252
324
  it('returns valid json response', async (context) => {
253
325
  const response = new Response(`{ "validJson": true }`, {
254
326
  status: 200,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unito/integration-sdk",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Integration SDK",
5
5
  "type": "module",
6
6
  "types": "dist/src/index.d.ts",
@@ -1,4 +1,5 @@
1
1
  import { buildHttpError } from '../errors.js';
2
+ import * as HttpErrors from '../httpErrors.js';
2
3
  import { Credentials } from '../middlewares/credentials.js';
3
4
  import Logger from '../resources/logger.js';
4
5
 
@@ -59,26 +60,56 @@ export type Response<T> = {
59
60
  * Defines methods for the following HTTP methods: GET, POST, PUT, PATCH, DELETE.
60
61
  *
61
62
  * Needs to be initialized with a prepareRequest function to define the Provider's base URL and any specific headers to
62
- * add to the requests, and can also be configured to use a provided rate limiting function.
63
+ * add to the requests, can also be configured to use a provided rate limiting function, and custom error handler.
64
+ *
65
+ * Multiple `Provider` instances can be created, with different configurations to call different providers APIs with
66
+ * different rateLimiting functions, as needed.
63
67
  * @see {@link RateLimiter}
64
68
  * @see {@link prepareRequest}
69
+ * @see {@link customErrorHandler}
65
70
  */
66
71
  export class Provider {
72
+ /**
73
+ * The Rate Limiter function to use to limit the rate of calls made to the provider based on the caller's credentials.
74
+ */
67
75
  protected rateLimiter: RateLimiter | undefined = undefined;
76
+ /**
77
+ * Function called before each request to define the Provider's base URL and any specific headers to add to the requests.
78
+ *
79
+ * This is applied at large to all requests made to the provider. If you need to add specific headers to a single request,
80
+ * pass it through the RequestOptions object when calling the Provider's methods.
81
+ */
68
82
  protected prepareRequest: (options: { credentials: Credentials; logger: Logger }) => {
69
83
  url: string;
70
84
  headers: Record<string, string>;
71
85
  };
86
+ /**
87
+ * (Optional) Custom error handler to handle specific errors returned by the provider.
88
+ *
89
+ * If provided, this method should only care about custom errors returned by the provider and return the corresponding
90
+ * HttpError from the SDK. If the error encountered is a standard error, it should return undefined and let the SDK handle it.
91
+ *
92
+ * @see buildHttpError for the list of standard errors the SDK can handle.
93
+ */
94
+ protected customErrorHandler:
95
+ | ((responseStatus: number, message: string) => HttpErrors.HttpError | undefined)
96
+ | undefined;
72
97
 
73
98
  /**
74
99
  * Initializes a Provider with the given options.
75
100
  *
76
101
  * @property prepareRequest - function to define the Provider's base URL and specific headers to add to the request.
77
102
  * @property rateLimiter - function to limit the rate of calls to the provider based on the caller's credentials.
103
+ * @property customErrorHandler - function to handle specific errors returned by the provider.
78
104
  */
79
- constructor(options: { prepareRequest: typeof Provider.prototype.prepareRequest; rateLimiter?: RateLimiter }) {
105
+ constructor(options: {
106
+ prepareRequest: typeof Provider.prototype.prepareRequest;
107
+ rateLimiter?: RateLimiter | undefined;
108
+ customErrorHandler?: typeof Provider.prototype.customErrorHandler;
109
+ }) {
80
110
  this.prepareRequest = options.prepareRequest;
81
111
  this.rateLimiter = options.rateLimiter;
112
+ this.customErrorHandler = options.customErrorHandler;
82
113
  }
83
114
 
84
115
  /**
@@ -262,18 +293,18 @@ export class Provider {
262
293
  if (error instanceof Error) {
263
294
  switch (error.name) {
264
295
  case 'AbortError':
265
- throw buildHttpError(408, 'Request aborted');
296
+ throw this.handleError(408, 'Request aborted');
266
297
  case 'TimeoutError':
267
- throw buildHttpError(408, 'Request timeout');
298
+ throw this.handleError(408, 'Request timeout');
268
299
  }
269
300
  }
270
301
 
271
- throw buildHttpError(500, `Unexpected error while calling the provider: "${error}"`);
302
+ throw this.handleError(500, `Unexpected error while calling the provider: "${error}"`);
272
303
  }
273
304
 
274
305
  if (response.status >= 400) {
275
306
  const textResult = await response.text();
276
- throw buildHttpError(response.status, textResult);
307
+ throw this.handleError(response.status, textResult);
277
308
  }
278
309
 
279
310
  const responseContentType = response.headers.get('content-type');
@@ -284,7 +315,7 @@ export class Provider {
284
315
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
285
316
  // Default to application/json if no Content-Type header is provided
286
317
  if (responseContentType && !responseContentType.includes('application/json')) {
287
- throw buildHttpError(
318
+ throw this.handleError(
288
319
  500,
289
320
  `Unsupported content-type. Expected 'application/json', got '${responseContentType}'`,
290
321
  );
@@ -293,13 +324,13 @@ export class Provider {
293
324
  try {
294
325
  body = response.body ? await response.json() : undefined;
295
326
  } catch (err) {
296
- throw buildHttpError(500, `Invalid JSON response`);
327
+ throw this.handleError(500, `Invalid JSON response`);
297
328
  }
298
329
  } else if (headers.Accept == 'application/octet-stream') {
299
330
  // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it.
300
331
  body = response.body as T;
301
332
  } else {
302
- throw buildHttpError(500, 'Unsupported accept header');
333
+ throw this.handleError(500, 'Unsupported accept header');
303
334
  }
304
335
 
305
336
  return { status: response.status, headers: response.headers, body };
@@ -307,4 +338,10 @@ export class Provider {
307
338
 
308
339
  return this.rateLimiter ? this.rateLimiter(options, callToProvider) : callToProvider();
309
340
  }
341
+
342
+ private handleError(responseStatus: number, message: string): HttpErrors.HttpError {
343
+ const customError = this.customErrorHandler?.(responseStatus, message);
344
+
345
+ return customError ?? buildHttpError(responseStatus, message);
346
+ }
310
347
  }
@@ -297,6 +297,89 @@ describe('Provider', () => {
297
297
  assert.deepEqual(actualResponse, { status: 204, headers: response.headers, body: undefined });
298
298
  });
299
299
 
300
+ it('uses custom error handler if provided', async context => {
301
+ const rateLimitedProvider = new Provider({
302
+ prepareRequest: requestOptions => {
303
+ return {
304
+ url: `www.${requestOptions.credentials.domain ?? 'myApi.com'}`,
305
+ headers: {
306
+ 'X-Custom-Provider-Header': 'value',
307
+ 'X-Provider-Credential-Header': requestOptions.credentials.apiKey as string,
308
+ },
309
+ };
310
+ },
311
+ rateLimiter: undefined,
312
+ // Change from normal behavior 400 -> 429
313
+ customErrorHandler: (responseStatus: number) =>
314
+ responseStatus === 400 ? new HttpErrors.RateLimitExceededError('Weird provider behavior') : undefined,
315
+ });
316
+
317
+ const response = new Response(undefined, {
318
+ status: 400,
319
+ headers: { 'Content-Type': 'application/json' },
320
+ });
321
+
322
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
323
+
324
+ const options = {
325
+ credentials: { apiKey: 'apikey#1111' },
326
+ logger: logger,
327
+ signal: new AbortController().signal,
328
+ additionnalheaders: { 'X-Additional-Header': 'value1' },
329
+ };
330
+
331
+ let error;
332
+ try {
333
+ await rateLimitedProvider.delete('/endpoint/123', options);
334
+ } catch (e) {
335
+ error = e;
336
+ }
337
+
338
+ assert.ok(error instanceof HttpErrors.HttpError);
339
+ assert.equal(error.message, 'Weird provider behavior');
340
+ });
341
+
342
+ it('uses default behavior if custom error handler returns undefined', async context => {
343
+ const rateLimitedProvider = new Provider({
344
+ prepareRequest: requestOptions => {
345
+ return {
346
+ url: `www.${requestOptions.credentials.domain ?? 'myApi.com'}`,
347
+ headers: {
348
+ 'X-Custom-Provider-Header': 'value',
349
+ 'X-Provider-Credential-Header': requestOptions.credentials.apiKey as string,
350
+ },
351
+ };
352
+ },
353
+ rateLimiter: undefined,
354
+ // Custom Error Handler returning undefined (default behavior should apply)
355
+ customErrorHandler: () => undefined,
356
+ });
357
+
358
+ const response = new Response(undefined, {
359
+ status: 404,
360
+ headers: { 'Content-Type': 'application/json' },
361
+ });
362
+
363
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
364
+
365
+ const options = {
366
+ credentials: { apiKey: 'apikey#1111' },
367
+ logger: logger,
368
+ signal: new AbortController().signal,
369
+ additionnalheaders: { 'X-Additional-Header': 'value1' },
370
+ };
371
+
372
+ let error;
373
+ try {
374
+ await rateLimitedProvider.delete('/endpoint/123', options);
375
+ } catch (e) {
376
+ error = e;
377
+ }
378
+
379
+ assert.ok(error instanceof HttpErrors.HttpError);
380
+ assert.equal(error.message, 'Not found');
381
+ });
382
+
300
383
  it('returns valid json response', async context => {
301
384
  const response = new Response(`{ "validJson": true }`, {
302
385
  status: 200,