Skip to content

Commit 1e1adc6

Browse files
authored
Refactor fetch handling to avoid illegal invocation errors (#1990)
* refactor fetch handling * avoid && taking precedence * add a test
1 parent 68c30ff commit 1e1adc6

File tree

8 files changed

+41
-28
lines changed

8 files changed

+41
-28
lines changed

.generator/src/generator/templates/configuration.j2

+2-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export function createConfiguration(conf: ConfigurationParameters = {}): Configu
188188
conf.baseServer,
189189
conf.serverIndex || 0,
190190
conf.operationServerIndices || {},
191-
conf.httpApi || new DefaultHttpLibrary({ fetch: conf.fetch }),
191+
conf.httpApi || new DefaultHttpLibrary(),
192192
configureAuthMethods(authMethods),
193193
conf.httpConfig || {},
194194
conf.debug,
@@ -214,6 +214,7 @@ export function createConfiguration(conf: ConfigurationParameters = {}): Configu
214214
configuration.httpApi.maxRetries = configuration.maxRetries;
215215
configuration.httpApi.backoffBase = configuration.backoffBase;
216216
configuration.httpApi.backoffMultiplier = configuration.backoffMultiplier;
217+
configuration.httpApi.fetch = conf.fetch;
217218
return configuration;
218219
}
219220

.generator/src/generator/templates/http/http.j2

+1
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ export interface HttpLibrary {
266266
backoffBase?: number;
267267
backoffMultiplier?: number;
268268
debug?: boolean;
269+
fetch?: any;
269270
zstdCompressorCallback?: ZstdCompressorCallback;
270271
send(request: RequestContext): Promise<ResponseContext>;
271272
}

.generator/src/generator/templates/http/isomorphic-fetch.j2

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
1212
public maxRetries!: number ;
1313
public backoffBase!: number ;
1414
public backoffMultiplier!: number;
15-
#fetch: any;
16-
17-
constructor({ fetch: customFetch }: { fetch?: any }) {
18-
this.#fetch =
19-
customFetch ||
20-
// On non-node environments, use native fetch if available.
21-
// `cross-fetch` incorrectly assumes all browsers have XHR available.
22-
// See https://github.com/lquixada/cross-fetch/issues/78
23-
// TODO: Remove once once above issue is resolved.
24-
(!isNode && typeof fetch === "function" ? fetch : crossFetch);
25-
}
15+
public fetch: any;
2616

2717
public send(request: RequestContext): Promise<ResponseContext> {
2818
if (this.debug) {
@@ -79,7 +69,14 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
7969
signal: request.getHttpConfig().signal,
8070
}
8171
try {
82-
const resp = await this.#fetch(request.getUrl(),fetchOptions);
72+
const fetchFunction = this.fetch ||
73+
// On non-node environments, use native fetch if available.
74+
// `cross-fetch` incorrectly assumes all browsers have XHR available.
75+
// See https://github.com/lquixada/cross-fetch/issues/78
76+
// TODO: Remove once once above issue is resolved.
77+
((!isNode && typeof fetch === "function") ? fetch : crossFetch);
78+
79+
const resp = await fetchFunction(request.getUrl(),fetchOptions);
8380
const responseHeaders: { [name: string]: string } = {};
8481
resp.headers.forEach((value: string, name: string) => {
8582
responseHeaders[name] = value;

packages/datadog-api-client-common/configuration.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export function createConfiguration(
213213
conf.baseServer,
214214
conf.serverIndex || 0,
215215
conf.operationServerIndices || {},
216-
conf.httpApi || new DefaultHttpLibrary({ fetch: conf.fetch }),
216+
conf.httpApi || new DefaultHttpLibrary(),
217217
configureAuthMethods(authMethods),
218218
conf.httpConfig || {},
219219
conf.debug,
@@ -312,6 +312,7 @@ export function createConfiguration(
312312
configuration.httpApi.maxRetries = configuration.maxRetries;
313313
configuration.httpApi.backoffBase = configuration.backoffBase;
314314
configuration.httpApi.backoffMultiplier = configuration.backoffMultiplier;
315+
configuration.httpApi.fetch = conf.fetch;
315316
return configuration;
316317
}
317318

packages/datadog-api-client-common/http/http.ts

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ export interface HttpLibrary {
274274
backoffBase?: number;
275275
backoffMultiplier?: number;
276276
debug?: boolean;
277+
fetch?: any;
277278
zstdCompressorCallback?: ZstdCompressorCallback;
278279
send(request: RequestContext): Promise<ResponseContext>;
279280
}

packages/datadog-api-client-common/http/isomorphic-fetch.ts

+10-12
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
1717
public maxRetries!: number;
1818
public backoffBase!: number;
1919
public backoffMultiplier!: number;
20-
#fetch: any;
21-
22-
constructor({ fetch: customFetch }: { fetch?: any }) {
23-
this.#fetch =
24-
customFetch ||
25-
// On non-node environments, use native fetch if available.
26-
// `cross-fetch` incorrectly assumes all browsers have XHR available.
27-
// See https://github.com/lquixada/cross-fetch/issues/78
28-
// TODO: Remove once once above issue is resolved.
29-
(!isNode && typeof fetch === "function" ? fetch : crossFetch);
30-
}
20+
public fetch: any;
3121

3222
public send(request: RequestContext): Promise<ResponseContext> {
3323
if (this.debug) {
@@ -84,7 +74,15 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
8474
signal: request.getHttpConfig().signal,
8575
};
8676
try {
87-
const resp = await this.#fetch(request.getUrl(), fetchOptions);
77+
const fetchFunction =
78+
this.fetch ||
79+
// On non-node environments, use native fetch if available.
80+
// `cross-fetch` incorrectly assumes all browsers have XHR available.
81+
// See https://github.com/lquixada/cross-fetch/issues/78
82+
// TODO: Remove once once above issue is resolved.
83+
(!isNode && typeof fetch === "function" ? fetch : crossFetch);
84+
85+
const resp = await fetchFunction(request.getUrl(), fetchOptions);
8886
const responseHeaders: { [name: string]: string } = {};
8987
resp.headers.forEach((value: string, name: string) => {
9088
responseHeaders[name] = value;

tests/api/retry.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
describe("IsomorphicFetchHttpLibrary Retry Test", () => {
1010

1111
const fakeRequestContext = new RequestContext("https://retry.test.com",HttpMethod.GET);
12-
const httpLibrary = new IsomorphicFetchHttpLibrary({fetch: null});
12+
const httpLibrary = new IsomorphicFetchHttpLibrary();
1313
httpLibrary['sleep'] = jest.fn(() => Promise.resolve());
1414
httpLibrary.enableRetry = true;
1515
httpLibrary.maxRetries = 3;

tests/api/server.test.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { createConfiguration } from "../../packages/datadog-api-client-common/co
33
import {
44
HttpMethod,
55
} from "../../packages/datadog-api-client-common/http/http";
6-
import { DashboardsApiRequestFactory } from '../../packages/datadog-api-client-v1/apis/DashboardsApi';
6+
import { DashboardsApiRequestFactory, DashboardsApi } from '../../packages/datadog-api-client-v1/apis/DashboardsApi';
7+
import { logger } from "../../logger";
78

89
test('TestServerClone', () => {
910
const newServer = server1.clone();
@@ -53,4 +54,17 @@ test ('TestBackoffBaseNoLessThanTwo',() => {
5354
};
5455
expect(()=> createConfiguration(configOpts)).toThrow();
5556
}
57+
);
58+
59+
test('TestCustomFetch', async () => {
60+
// Mock logger to prevent writing to console during test
61+
logger.error = jest.fn();
62+
// Mock fetch
63+
const _fetch = jest.fn(() => Promise.resolve());
64+
const config = createConfiguration({fetch: _fetch});
65+
const api = new DashboardsApi(config);
66+
await expect(api.deleteDashboard({dashboardId: "id"})).rejects.toThrow();
67+
68+
expect(_fetch).toHaveBeenCalledTimes(1);
69+
}
5670
);

0 commit comments

Comments
 (0)