@datocms/rest-client-utils 6.1.0 → 6.1.1
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.
- package/dist/cjs/__tests__/request.test.js +85 -0
- package/dist/cjs/__tests__/request.test.js.map +1 -0
- package/dist/cjs/errors.js +14 -0
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/request.js +35 -7
- package/dist/cjs/request.js.map +1 -1
- package/dist/esm/__tests__/request.test.d.ts +1 -0
- package/dist/esm/__tests__/request.test.js +78 -0
- package/dist/esm/__tests__/request.test.js.map +1 -0
- package/dist/esm/errors.js +14 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/request.js +35 -7
- package/dist/esm/request.js.map +1 -1
- package/dist/types/__tests__/request.test.d.ts +1 -0
- package/package.json +1 -1
- package/src/__tests__/request.test.ts +105 -0
- package/src/errors.ts +17 -0
- package/src/request.ts +44 -8
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const errors_1 = require("../errors");
|
|
13
|
+
const request_1 = require("../request");
|
|
14
|
+
const API_TOKEN = 'aaaabbbbccccdddd';
|
|
15
|
+
function jsonResponse(status, body) {
|
|
16
|
+
return new Response(JSON.stringify(body), {
|
|
17
|
+
status,
|
|
18
|
+
statusText: 'Unprocessable Entity',
|
|
19
|
+
headers: { 'Content-Type': 'application/json' },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function buildOptions(fetchFn) {
|
|
23
|
+
return {
|
|
24
|
+
baseUrl: 'https://site-api.datocms.com',
|
|
25
|
+
fetchJobResult: () => __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
throw new Error('not needed');
|
|
27
|
+
}),
|
|
28
|
+
fetchFn,
|
|
29
|
+
apiToken: API_TOKEN,
|
|
30
|
+
method: 'GET',
|
|
31
|
+
url: '/items/bad-id',
|
|
32
|
+
autoRetry: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
describe('request()', () => {
|
|
36
|
+
it('sends the real API token, but keeps it out of the error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
let sentAuthorization;
|
|
38
|
+
const fetchFn = jest.fn((_url, init) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
var _a;
|
|
40
|
+
sentAuthorization = (_a = init === null || init === void 0 ? void 0 : init.headers) === null || _a === void 0 ? void 0 : _a.authorization;
|
|
41
|
+
return jsonResponse(422, { data: [] });
|
|
42
|
+
}));
|
|
43
|
+
const error = yield (0, request_1.request)(buildOptions(fetchFn)).then(() => {
|
|
44
|
+
throw new Error('expected the request to fail');
|
|
45
|
+
}, (error) => error);
|
|
46
|
+
expect(error).toBeInstanceOf(errors_1.ApiError);
|
|
47
|
+
expect(sentAuthorization).toBe(`Bearer ${API_TOKEN}`);
|
|
48
|
+
expect(error.request.headers.authorization).toBe('[REDACTED, ending in dddd]');
|
|
49
|
+
expect(JSON.stringify(error)).not.toContain(API_TOKEN);
|
|
50
|
+
}));
|
|
51
|
+
it('keeps the token out of a timeout error too', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const fetchFn = (() => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
const error = new Error('timeout');
|
|
54
|
+
error.code = 'ETIMEDOUT';
|
|
55
|
+
throw error;
|
|
56
|
+
}));
|
|
57
|
+
const error = yield (0, request_1.request)(Object.assign(Object.assign({}, buildOptions(fetchFn)), { autoRetry: false })).then(() => {
|
|
58
|
+
throw new Error('expected the request to fail');
|
|
59
|
+
}, (error) => error);
|
|
60
|
+
expect(error).toBeInstanceOf(errors_1.TimeoutError);
|
|
61
|
+
expect(error.request.headers.authorization).toBe('[REDACTED, ending in dddd]');
|
|
62
|
+
}));
|
|
63
|
+
it('does not spill the failed call through incidental serialization', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
const fetchFn = (() => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
return jsonResponse(422, {
|
|
66
|
+
data: [],
|
|
67
|
+
});
|
|
68
|
+
}));
|
|
69
|
+
const error = yield (0, request_1.request)(Object.assign(Object.assign({}, buildOptions(fetchFn)), { body: {
|
|
70
|
+
data: { attributes: { url: 'https://example.com/?token=s3cr3t' } },
|
|
71
|
+
} })).then(() => {
|
|
72
|
+
throw new Error('expected the request to fail');
|
|
73
|
+
}, (error) => error);
|
|
74
|
+
// `request` and `response` stay readable...
|
|
75
|
+
expect(error.request.url).toContain('/items/bad-id');
|
|
76
|
+
expect(error.response.status).toBe(422);
|
|
77
|
+
// ...but no longer travel by accident: this is what `console.error()`,
|
|
78
|
+
// `serialize-error` and most error trackers walk.
|
|
79
|
+
expect(Object.keys(error)).not.toContain('request');
|
|
80
|
+
expect(Object.keys(error)).not.toContain('response');
|
|
81
|
+
expect(JSON.stringify(error)).not.toContain('s3cr3t');
|
|
82
|
+
expect(JSON.stringify(Object.assign({}, error))).not.toContain('s3cr3t');
|
|
83
|
+
}));
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=request.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.test.js","sourceRoot":"","sources":["../../../src/__tests__/request.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/errors.js
CHANGED
|
@@ -36,6 +36,18 @@ function isErrorBody(body) {
|
|
|
36
36
|
*/
|
|
37
37
|
const TIMEOUT_ERROR = Symbol.for('@datocms/rest-client-utils:TimeoutError');
|
|
38
38
|
const API_ERROR = Symbol.for('@datocms/rest-client-utils:ApiError');
|
|
39
|
+
/**
|
|
40
|
+
* Hides properties from anything that walks own enumerable keys —
|
|
41
|
+
* `console.error()`, `JSON.stringify()`, object spread, `serialize-error`,
|
|
42
|
+
* error trackers. Reading `error.request` explicitly keeps working exactly as
|
|
43
|
+
* before; the data just stops travelling by accident, since the request and
|
|
44
|
+
* response of a failed call can carry credentials and other secrets.
|
|
45
|
+
*/
|
|
46
|
+
function hideProperties(target, keys) {
|
|
47
|
+
for (const key of keys) {
|
|
48
|
+
Object.defineProperty(target, key, { enumerable: false });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
class TimeoutError extends Error {
|
|
40
52
|
static [Symbol.hasInstance](value) {
|
|
41
53
|
if (typeof value !== 'object' ||
|
|
@@ -70,6 +82,7 @@ class TimeoutError extends Error {
|
|
|
70
82
|
}
|
|
71
83
|
this.request = initObject.request;
|
|
72
84
|
this.preCallStack = initObject.preCallStack;
|
|
85
|
+
hideProperties(this, ['request', 'preCallStack']);
|
|
73
86
|
this.message = `${initObject.request.method} ${initObject.request.url}: Timeout error`;
|
|
74
87
|
if (this.preCallStack) {
|
|
75
88
|
this.stack += `\nCaused By:\n${this.preCallStack}`;
|
|
@@ -110,6 +123,7 @@ class ApiError extends Error {
|
|
|
110
123
|
this.request = initObject.request;
|
|
111
124
|
this.response = initObject.response;
|
|
112
125
|
this.preCallStack = initObject.preCallStack;
|
|
126
|
+
hideProperties(this, ['request', 'response', 'preCallStack']);
|
|
113
127
|
let message = `${initObject.request.method} ${initObject.request.url}: ${this.response.status} ${this.response.statusText}`;
|
|
114
128
|
if (this.errors.length > 0) {
|
|
115
129
|
message += `\n\n${JSON.stringify(this.errors, null, 2)}`;
|
package/dist/cjs/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAcA,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE;QAClE,OAAO,KAAK,CAAC;KACd;IAED,MAAM,YAAY,GAAG,IAAyB,CAAC;IAE/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;QACrC,OAAO,KAAK,CAAC;KACd;IAED,MAAM,gBAAgB,GAAG,YAAmC,CAAC;IAE7D,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,OAAO,KAAK,CAAC;KACd;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzC,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC;QAClB,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC;QACpB,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC;QACzB,OAAuB,CAAC,IAAI,KAAK,WAAW,EAC7C;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD;;;;;;;;;GASG;AACH,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/request.js
CHANGED
|
@@ -35,6 +35,28 @@ function headersToObject(headers) {
|
|
|
35
35
|
});
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Headers whose value must never end up inside an error object.
|
|
40
|
+
*
|
|
41
|
+
* Right now this client only ever sets one of them, but the list is the point:
|
|
42
|
+
* a header added here is redacted everywhere an error can reach.
|
|
43
|
+
*/
|
|
44
|
+
const SENSITIVE_HEADERS = ['authorization'];
|
|
45
|
+
/**
|
|
46
|
+
* Returns a copy of the request headers with every sensitive value blanked out.
|
|
47
|
+
*
|
|
48
|
+
* Errors travel: they get logged, serialized, sent to error trackers, and — as
|
|
49
|
+
* we learned the hard way — occasionally echoed back to an HTTP client. The
|
|
50
|
+
* real headers are only ever handed to `fetch()`; what we keep on the error is
|
|
51
|
+
* this redacted copy.
|
|
52
|
+
*/
|
|
53
|
+
function redactHeaders(headers) {
|
|
54
|
+
return Object.fromEntries(Object.entries(headers).map(([key, value]) => SENSITIVE_HEADERS.includes(key.toLowerCase())
|
|
55
|
+
? // The last 4 characters are enough to tell two tokens apart while
|
|
56
|
+
// debugging, and useless to whoever gets hold of the log.
|
|
57
|
+
[key, `[REDACTED, ending in ${value.slice(-4)}]`]
|
|
58
|
+
: [key, value]));
|
|
59
|
+
}
|
|
38
60
|
function buildApiErrorInitObject(method, url, requestHeaders, requestBody, response, responseBody, preCallStack) {
|
|
39
61
|
return {
|
|
40
62
|
request: {
|
|
@@ -114,6 +136,7 @@ function request(options) {
|
|
|
114
136
|
// user agent cannot be set on browser
|
|
115
137
|
delete headers['user-agent'];
|
|
116
138
|
}
|
|
139
|
+
const redactedHeaders = redactHeaders(headers);
|
|
117
140
|
const baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
118
141
|
const body = options.body ? JSON.stringify(options.body, null, 2) : undefined;
|
|
119
142
|
const queryString = options.queryParams && Object.keys(options.queryParams).length > 0
|
|
@@ -123,7 +146,7 @@ function request(options) {
|
|
|
123
146
|
if (logLevel >= LogLevel.BASIC) {
|
|
124
147
|
log(`[${requestId}] ${options.method} ${url}`);
|
|
125
148
|
if (logLevel >= LogLevel.BODY_AND_HEADERS) {
|
|
126
|
-
for (const [key, value] of Object.entries(
|
|
149
|
+
for (const [key, value] of Object.entries(redactedHeaders)) {
|
|
127
150
|
log(`[${requestId}] ${key}: ${value}`);
|
|
128
151
|
}
|
|
129
152
|
}
|
|
@@ -131,22 +154,24 @@ function request(options) {
|
|
|
131
154
|
log(`[${requestId}] ${body}`);
|
|
132
155
|
}
|
|
133
156
|
}
|
|
157
|
+
// Declared out here so that the `finally` below can always clear it: a timer
|
|
158
|
+
// left pending keeps Node's event loop alive for as long as it runs.
|
|
159
|
+
let timeoutId;
|
|
134
160
|
try {
|
|
135
161
|
const requestPromise = (0, makeCancelablePromise_js_1.makeCancelablePromise)(fetchFn(url, {
|
|
136
162
|
method: options.method,
|
|
137
163
|
headers,
|
|
138
164
|
body,
|
|
139
165
|
}));
|
|
140
|
-
|
|
166
|
+
timeoutId = setTimeout(() => {
|
|
141
167
|
requestPromise.cancel();
|
|
142
168
|
}, options.requestTimeout || 30000);
|
|
143
169
|
const response = yield requestPromise;
|
|
144
|
-
clearTimeout(timeoutId);
|
|
145
170
|
const responseContentType = response.headers.get('Content-Type');
|
|
146
171
|
const invalidContentType = responseContentType && !responseContentType.includes('application/json');
|
|
147
172
|
if (response.status === 429 || invalidContentType) {
|
|
148
173
|
if (!autoRetry || (invalidContentType && options.method !== 'GET')) {
|
|
149
|
-
throw new errors_js_1.ApiError(buildApiErrorInitObject(options.method, url,
|
|
174
|
+
throw new errors_js_1.ApiError(buildApiErrorInitObject(options.method, url, redactedHeaders, options.body, response, undefined, preCallStack));
|
|
150
175
|
}
|
|
151
176
|
const waitTimeInSecs = response.headers.has('X-RateLimit-Reset')
|
|
152
177
|
? Number.parseInt(response.headers.get('X-RateLimit-Reset'), 10)
|
|
@@ -187,14 +212,14 @@ function request(options) {
|
|
|
187
212
|
if (response.status === 202) {
|
|
188
213
|
const jobResult = yield options.fetchJobResult(responseBody.data.id);
|
|
189
214
|
if (jobResult.status < 200 || jobResult.status >= 300) {
|
|
190
|
-
throw new errors_js_1.ApiError(buildApiErrorInitObjectFromJobResult(options.method, url,
|
|
215
|
+
throw new errors_js_1.ApiError(buildApiErrorInitObjectFromJobResult(options.method, url, redactedHeaders, options.body, jobResult.status, jobResult.payload, preCallStack));
|
|
191
216
|
}
|
|
192
217
|
responseBody = jobResult.payload;
|
|
193
218
|
}
|
|
194
219
|
if (response.status >= 200 && response.status < 300) {
|
|
195
220
|
return responseBody;
|
|
196
221
|
}
|
|
197
|
-
const error = new errors_js_1.ApiError(buildApiErrorInitObject(options.method, url,
|
|
222
|
+
const error = new errors_js_1.ApiError(buildApiErrorInitObject(options.method, url, redactedHeaders, options.body, response, responseBody, preCallStack));
|
|
198
223
|
const transientErrorCode = (_a = error.errors.find((e) => e.attributes.transient)) === null || _a === void 0 ? void 0 : _a.attributes.code;
|
|
199
224
|
if (autoRetry && transientErrorCode) {
|
|
200
225
|
if (logLevel >= LogLevel.BASIC) {
|
|
@@ -215,10 +240,13 @@ function request(options) {
|
|
|
215
240
|
yield (0, wait_js_1.wait)(retryCount * 1000);
|
|
216
241
|
return request(Object.assign(Object.assign({}, options), { retryCount: retryCount + 1 }));
|
|
217
242
|
}
|
|
218
|
-
throw new errors_js_1.TimeoutError(buildTimeoutErrorInitObject(options.method, url,
|
|
243
|
+
throw new errors_js_1.TimeoutError(buildTimeoutErrorInitObject(options.method, url, redactedHeaders, options.body, preCallStack));
|
|
219
244
|
}
|
|
220
245
|
throw error;
|
|
221
246
|
}
|
|
247
|
+
finally {
|
|
248
|
+
clearTimeout(timeoutId);
|
|
249
|
+
}
|
|
222
250
|
});
|
|
223
251
|
}
|
|
224
252
|
exports.request = request;
|
package/dist/cjs/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ApiError, TimeoutError } from '../errors';
|
|
2
|
+
import { request } from '../request';
|
|
3
|
+
const API_TOKEN = 'aaaabbbbccccdddd';
|
|
4
|
+
function jsonResponse(status, body) {
|
|
5
|
+
return new Response(JSON.stringify(body), {
|
|
6
|
+
status,
|
|
7
|
+
statusText: 'Unprocessable Entity',
|
|
8
|
+
headers: { 'Content-Type': 'application/json' },
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function buildOptions(fetchFn) {
|
|
12
|
+
return {
|
|
13
|
+
baseUrl: 'https://site-api.datocms.com',
|
|
14
|
+
fetchJobResult: async () => {
|
|
15
|
+
throw new Error('not needed');
|
|
16
|
+
},
|
|
17
|
+
fetchFn,
|
|
18
|
+
apiToken: API_TOKEN,
|
|
19
|
+
method: 'GET',
|
|
20
|
+
url: '/items/bad-id',
|
|
21
|
+
autoRetry: false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
describe('request()', () => {
|
|
25
|
+
it('sends the real API token, but keeps it out of the error', async () => {
|
|
26
|
+
let sentAuthorization;
|
|
27
|
+
const fetchFn = jest.fn(async (_url, init) => {
|
|
28
|
+
var _a;
|
|
29
|
+
sentAuthorization = (_a = init === null || init === void 0 ? void 0 : init.headers) === null || _a === void 0 ? void 0 : _a.authorization;
|
|
30
|
+
return jsonResponse(422, { data: [] });
|
|
31
|
+
});
|
|
32
|
+
const error = await request(buildOptions(fetchFn)).then(() => {
|
|
33
|
+
throw new Error('expected the request to fail');
|
|
34
|
+
}, (error) => error);
|
|
35
|
+
expect(error).toBeInstanceOf(ApiError);
|
|
36
|
+
expect(sentAuthorization).toBe(`Bearer ${API_TOKEN}`);
|
|
37
|
+
expect(error.request.headers.authorization).toBe('[REDACTED, ending in dddd]');
|
|
38
|
+
expect(JSON.stringify(error)).not.toContain(API_TOKEN);
|
|
39
|
+
});
|
|
40
|
+
it('keeps the token out of a timeout error too', async () => {
|
|
41
|
+
const fetchFn = (async () => {
|
|
42
|
+
const error = new Error('timeout');
|
|
43
|
+
error.code = 'ETIMEDOUT';
|
|
44
|
+
throw error;
|
|
45
|
+
});
|
|
46
|
+
const error = await request({
|
|
47
|
+
...buildOptions(fetchFn),
|
|
48
|
+
autoRetry: false,
|
|
49
|
+
}).then(() => {
|
|
50
|
+
throw new Error('expected the request to fail');
|
|
51
|
+
}, (error) => error);
|
|
52
|
+
expect(error).toBeInstanceOf(TimeoutError);
|
|
53
|
+
expect(error.request.headers.authorization).toBe('[REDACTED, ending in dddd]');
|
|
54
|
+
});
|
|
55
|
+
it('does not spill the failed call through incidental serialization', async () => {
|
|
56
|
+
const fetchFn = (async () => jsonResponse(422, {
|
|
57
|
+
data: [],
|
|
58
|
+
}));
|
|
59
|
+
const error = await request({
|
|
60
|
+
...buildOptions(fetchFn),
|
|
61
|
+
body: {
|
|
62
|
+
data: { attributes: { url: 'https://example.com/?token=s3cr3t' } },
|
|
63
|
+
},
|
|
64
|
+
}).then(() => {
|
|
65
|
+
throw new Error('expected the request to fail');
|
|
66
|
+
}, (error) => error);
|
|
67
|
+
// `request` and `response` stay readable...
|
|
68
|
+
expect(error.request.url).toContain('/items/bad-id');
|
|
69
|
+
expect(error.response.status).toBe(422);
|
|
70
|
+
// ...but no longer travel by accident: this is what `console.error()`,
|
|
71
|
+
// `serialize-error` and most error trackers walk.
|
|
72
|
+
expect(Object.keys(error)).not.toContain('request');
|
|
73
|
+
expect(Object.keys(error)).not.toContain('response');
|
|
74
|
+
expect(JSON.stringify(error)).not.toContain('s3cr3t');
|
|
75
|
+
expect(JSON.stringify({ ...error })).not.toContain('s3cr3t');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=request.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.test.js","sourceRoot":"","sources":["../../../src/__tests__/request.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/errors.js
CHANGED
|
@@ -33,6 +33,18 @@ function isErrorBody(body) {
|
|
|
33
33
|
*/
|
|
34
34
|
const TIMEOUT_ERROR = Symbol.for('@datocms/rest-client-utils:TimeoutError');
|
|
35
35
|
const API_ERROR = Symbol.for('@datocms/rest-client-utils:ApiError');
|
|
36
|
+
/**
|
|
37
|
+
* Hides properties from anything that walks own enumerable keys —
|
|
38
|
+
* `console.error()`, `JSON.stringify()`, object spread, `serialize-error`,
|
|
39
|
+
* error trackers. Reading `error.request` explicitly keeps working exactly as
|
|
40
|
+
* before; the data just stops travelling by accident, since the request and
|
|
41
|
+
* response of a failed call can carry credentials and other secrets.
|
|
42
|
+
*/
|
|
43
|
+
function hideProperties(target, keys) {
|
|
44
|
+
for (const key of keys) {
|
|
45
|
+
Object.defineProperty(target, key, { enumerable: false });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
36
48
|
export class TimeoutError extends Error {
|
|
37
49
|
static [Symbol.hasInstance](value) {
|
|
38
50
|
if (typeof value !== 'object' ||
|
|
@@ -67,6 +79,7 @@ export class TimeoutError extends Error {
|
|
|
67
79
|
}
|
|
68
80
|
this.request = initObject.request;
|
|
69
81
|
this.preCallStack = initObject.preCallStack;
|
|
82
|
+
hideProperties(this, ['request', 'preCallStack']);
|
|
70
83
|
this.message = `${initObject.request.method} ${initObject.request.url}: Timeout error`;
|
|
71
84
|
if (this.preCallStack) {
|
|
72
85
|
this.stack += `\nCaused By:\n${this.preCallStack}`;
|
|
@@ -106,6 +119,7 @@ export class ApiError extends Error {
|
|
|
106
119
|
this.request = initObject.request;
|
|
107
120
|
this.response = initObject.response;
|
|
108
121
|
this.preCallStack = initObject.preCallStack;
|
|
122
|
+
hideProperties(this, ['request', 'response', 'preCallStack']);
|
|
109
123
|
let message = `${initObject.request.method} ${initObject.request.url}: ${this.response.status} ${this.response.statusText}`;
|
|
110
124
|
if (this.errors.length > 0) {
|
|
111
125
|
message += `\n\n${JSON.stringify(this.errors, null, 2)}`;
|
package/dist/esm/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAcA,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE;QAClE,OAAO,KAAK,CAAC;KACd;IAED,MAAM,YAAY,GAAG,IAAyB,CAAC;IAE/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;QACrC,OAAO,KAAK,CAAC;KACd;IAED,MAAM,gBAAgB,GAAG,YAAmC,CAAC;IAE7D,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,OAAO,KAAK,CAAC;KACd;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzC,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC;QAClB,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC;QACpB,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC;QACzB,OAAuB,CAAC,IAAI,KAAK,WAAW,EAC7C;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD;;;;;;;;;GASG;AACH,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/request.js
CHANGED
|
@@ -23,6 +23,28 @@ function headersToObject(headers) {
|
|
|
23
23
|
});
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Headers whose value must never end up inside an error object.
|
|
28
|
+
*
|
|
29
|
+
* Right now this client only ever sets one of them, but the list is the point:
|
|
30
|
+
* a header added here is redacted everywhere an error can reach.
|
|
31
|
+
*/
|
|
32
|
+
const SENSITIVE_HEADERS = ['authorization'];
|
|
33
|
+
/**
|
|
34
|
+
* Returns a copy of the request headers with every sensitive value blanked out.
|
|
35
|
+
*
|
|
36
|
+
* Errors travel: they get logged, serialized, sent to error trackers, and — as
|
|
37
|
+
* we learned the hard way — occasionally echoed back to an HTTP client. The
|
|
38
|
+
* real headers are only ever handed to `fetch()`; what we keep on the error is
|
|
39
|
+
* this redacted copy.
|
|
40
|
+
*/
|
|
41
|
+
function redactHeaders(headers) {
|
|
42
|
+
return Object.fromEntries(Object.entries(headers).map(([key, value]) => SENSITIVE_HEADERS.includes(key.toLowerCase())
|
|
43
|
+
? // The last 4 characters are enough to tell two tokens apart while
|
|
44
|
+
// debugging, and useless to whoever gets hold of the log.
|
|
45
|
+
[key, `[REDACTED, ending in ${value.slice(-4)}]`]
|
|
46
|
+
: [key, value]));
|
|
47
|
+
}
|
|
26
48
|
function buildApiErrorInitObject(method, url, requestHeaders, requestBody, response, responseBody, preCallStack) {
|
|
27
49
|
return {
|
|
28
50
|
request: {
|
|
@@ -106,6 +128,7 @@ export async function request(options) {
|
|
|
106
128
|
// user agent cannot be set on browser
|
|
107
129
|
delete headers['user-agent'];
|
|
108
130
|
}
|
|
131
|
+
const redactedHeaders = redactHeaders(headers);
|
|
109
132
|
const baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
110
133
|
const body = options.body ? JSON.stringify(options.body, null, 2) : undefined;
|
|
111
134
|
const queryString = options.queryParams && Object.keys(options.queryParams).length > 0
|
|
@@ -115,7 +138,7 @@ export async function request(options) {
|
|
|
115
138
|
if (logLevel >= LogLevel.BASIC) {
|
|
116
139
|
log(`[${requestId}] ${options.method} ${url}`);
|
|
117
140
|
if (logLevel >= LogLevel.BODY_AND_HEADERS) {
|
|
118
|
-
for (const [key, value] of Object.entries(
|
|
141
|
+
for (const [key, value] of Object.entries(redactedHeaders)) {
|
|
119
142
|
log(`[${requestId}] ${key}: ${value}`);
|
|
120
143
|
}
|
|
121
144
|
}
|
|
@@ -123,22 +146,24 @@ export async function request(options) {
|
|
|
123
146
|
log(`[${requestId}] ${body}`);
|
|
124
147
|
}
|
|
125
148
|
}
|
|
149
|
+
// Declared out here so that the `finally` below can always clear it: a timer
|
|
150
|
+
// left pending keeps Node's event loop alive for as long as it runs.
|
|
151
|
+
let timeoutId;
|
|
126
152
|
try {
|
|
127
153
|
const requestPromise = makeCancelablePromise(fetchFn(url, {
|
|
128
154
|
method: options.method,
|
|
129
155
|
headers,
|
|
130
156
|
body,
|
|
131
157
|
}));
|
|
132
|
-
|
|
158
|
+
timeoutId = setTimeout(() => {
|
|
133
159
|
requestPromise.cancel();
|
|
134
160
|
}, options.requestTimeout || 30000);
|
|
135
161
|
const response = await requestPromise;
|
|
136
|
-
clearTimeout(timeoutId);
|
|
137
162
|
const responseContentType = response.headers.get('Content-Type');
|
|
138
163
|
const invalidContentType = responseContentType && !responseContentType.includes('application/json');
|
|
139
164
|
if (response.status === 429 || invalidContentType) {
|
|
140
165
|
if (!autoRetry || (invalidContentType && options.method !== 'GET')) {
|
|
141
|
-
throw new ApiError(buildApiErrorInitObject(options.method, url,
|
|
166
|
+
throw new ApiError(buildApiErrorInitObject(options.method, url, redactedHeaders, options.body, response, undefined, preCallStack));
|
|
142
167
|
}
|
|
143
168
|
const waitTimeInSecs = response.headers.has('X-RateLimit-Reset')
|
|
144
169
|
? Number.parseInt(response.headers.get('X-RateLimit-Reset'), 10)
|
|
@@ -179,14 +204,14 @@ export async function request(options) {
|
|
|
179
204
|
if (response.status === 202) {
|
|
180
205
|
const jobResult = await options.fetchJobResult(responseBody.data.id);
|
|
181
206
|
if (jobResult.status < 200 || jobResult.status >= 300) {
|
|
182
|
-
throw new ApiError(buildApiErrorInitObjectFromJobResult(options.method, url,
|
|
207
|
+
throw new ApiError(buildApiErrorInitObjectFromJobResult(options.method, url, redactedHeaders, options.body, jobResult.status, jobResult.payload, preCallStack));
|
|
183
208
|
}
|
|
184
209
|
responseBody = jobResult.payload;
|
|
185
210
|
}
|
|
186
211
|
if (response.status >= 200 && response.status < 300) {
|
|
187
212
|
return responseBody;
|
|
188
213
|
}
|
|
189
|
-
const error = new ApiError(buildApiErrorInitObject(options.method, url,
|
|
214
|
+
const error = new ApiError(buildApiErrorInitObject(options.method, url, redactedHeaders, options.body, response, responseBody, preCallStack));
|
|
190
215
|
const transientErrorCode = (_a = error.errors.find((e) => e.attributes.transient)) === null || _a === void 0 ? void 0 : _a.attributes.code;
|
|
191
216
|
if (autoRetry && transientErrorCode) {
|
|
192
217
|
if (logLevel >= LogLevel.BASIC) {
|
|
@@ -207,9 +232,12 @@ export async function request(options) {
|
|
|
207
232
|
await wait(retryCount * 1000);
|
|
208
233
|
return request({ ...options, retryCount: retryCount + 1 });
|
|
209
234
|
}
|
|
210
|
-
throw new TimeoutError(buildTimeoutErrorInitObject(options.method, url,
|
|
235
|
+
throw new TimeoutError(buildTimeoutErrorInitObject(options.method, url, redactedHeaders, options.body, preCallStack));
|
|
211
236
|
}
|
|
212
237
|
throw error;
|
|
213
238
|
}
|
|
239
|
+
finally {
|
|
240
|
+
clearTimeout(timeoutId);
|
|
241
|
+
}
|
|
214
242
|
}
|
|
215
243
|
//# sourceMappingURL=request.js.map
|
package/dist/esm/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ApiError, TimeoutError } from '../errors';
|
|
2
|
+
import { request } from '../request';
|
|
3
|
+
|
|
4
|
+
const API_TOKEN = 'aaaabbbbccccdddd';
|
|
5
|
+
|
|
6
|
+
function jsonResponse(status: number, body: unknown) {
|
|
7
|
+
return new Response(JSON.stringify(body), {
|
|
8
|
+
status,
|
|
9
|
+
statusText: 'Unprocessable Entity',
|
|
10
|
+
headers: { 'Content-Type': 'application/json' },
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function buildOptions(fetchFn: typeof fetch) {
|
|
15
|
+
return {
|
|
16
|
+
baseUrl: 'https://site-api.datocms.com',
|
|
17
|
+
fetchJobResult: async () => {
|
|
18
|
+
throw new Error('not needed');
|
|
19
|
+
},
|
|
20
|
+
fetchFn,
|
|
21
|
+
apiToken: API_TOKEN,
|
|
22
|
+
method: 'GET' as const,
|
|
23
|
+
url: '/items/bad-id',
|
|
24
|
+
autoRetry: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('request()', () => {
|
|
29
|
+
it('sends the real API token, but keeps it out of the error', async () => {
|
|
30
|
+
let sentAuthorization: string | undefined;
|
|
31
|
+
|
|
32
|
+
const fetchFn = jest.fn(async (_url: unknown, init?: RequestInit) => {
|
|
33
|
+
sentAuthorization = (init?.headers as Record<string, string>)
|
|
34
|
+
?.authorization;
|
|
35
|
+
return jsonResponse(422, { data: [] });
|
|
36
|
+
}) as unknown as typeof fetch;
|
|
37
|
+
|
|
38
|
+
const error: ApiError = await request(buildOptions(fetchFn)).then(
|
|
39
|
+
() => {
|
|
40
|
+
throw new Error('expected the request to fail');
|
|
41
|
+
},
|
|
42
|
+
(error) => error,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(error).toBeInstanceOf(ApiError);
|
|
46
|
+
expect(sentAuthorization).toBe(`Bearer ${API_TOKEN}`);
|
|
47
|
+
expect(error.request.headers.authorization).toBe(
|
|
48
|
+
'[REDACTED, ending in dddd]',
|
|
49
|
+
);
|
|
50
|
+
expect(JSON.stringify(error)).not.toContain(API_TOKEN);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('keeps the token out of a timeout error too', async () => {
|
|
54
|
+
const fetchFn = (async () => {
|
|
55
|
+
const error: NodeJS.ErrnoException = new Error('timeout');
|
|
56
|
+
error.code = 'ETIMEDOUT';
|
|
57
|
+
throw error;
|
|
58
|
+
}) as unknown as typeof fetch;
|
|
59
|
+
|
|
60
|
+
const error: TimeoutError = await request({
|
|
61
|
+
...buildOptions(fetchFn),
|
|
62
|
+
autoRetry: false,
|
|
63
|
+
}).then(
|
|
64
|
+
() => {
|
|
65
|
+
throw new Error('expected the request to fail');
|
|
66
|
+
},
|
|
67
|
+
(error) => error,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(error).toBeInstanceOf(TimeoutError);
|
|
71
|
+
expect(error.request.headers.authorization).toBe(
|
|
72
|
+
'[REDACTED, ending in dddd]',
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('does not spill the failed call through incidental serialization', async () => {
|
|
77
|
+
const fetchFn = (async () =>
|
|
78
|
+
jsonResponse(422, {
|
|
79
|
+
data: [],
|
|
80
|
+
})) as unknown as typeof fetch;
|
|
81
|
+
|
|
82
|
+
const error: ApiError = await request({
|
|
83
|
+
...buildOptions(fetchFn),
|
|
84
|
+
body: {
|
|
85
|
+
data: { attributes: { url: 'https://example.com/?token=s3cr3t' } },
|
|
86
|
+
},
|
|
87
|
+
}).then(
|
|
88
|
+
() => {
|
|
89
|
+
throw new Error('expected the request to fail');
|
|
90
|
+
},
|
|
91
|
+
(error) => error,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// `request` and `response` stay readable...
|
|
95
|
+
expect(error.request.url).toContain('/items/bad-id');
|
|
96
|
+
expect(error.response.status).toBe(422);
|
|
97
|
+
|
|
98
|
+
// ...but no longer travel by accident: this is what `console.error()`,
|
|
99
|
+
// `serialize-error` and most error trackers walk.
|
|
100
|
+
expect(Object.keys(error)).not.toContain('request');
|
|
101
|
+
expect(Object.keys(error)).not.toContain('response');
|
|
102
|
+
expect(JSON.stringify(error)).not.toContain('s3cr3t');
|
|
103
|
+
expect(JSON.stringify({ ...error })).not.toContain('s3cr3t');
|
|
104
|
+
});
|
|
105
|
+
});
|
package/src/errors.ts
CHANGED
|
@@ -72,6 +72,19 @@ export type ApiErrorResponse = {
|
|
|
72
72
|
const TIMEOUT_ERROR = Symbol.for('@datocms/rest-client-utils:TimeoutError');
|
|
73
73
|
const API_ERROR = Symbol.for('@datocms/rest-client-utils:ApiError');
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Hides properties from anything that walks own enumerable keys —
|
|
77
|
+
* `console.error()`, `JSON.stringify()`, object spread, `serialize-error`,
|
|
78
|
+
* error trackers. Reading `error.request` explicitly keeps working exactly as
|
|
79
|
+
* before; the data just stops travelling by accident, since the request and
|
|
80
|
+
* response of a failed call can carry credentials and other secrets.
|
|
81
|
+
*/
|
|
82
|
+
function hideProperties(target: object, keys: string[]) {
|
|
83
|
+
for (const key of keys) {
|
|
84
|
+
Object.defineProperty(target, key, { enumerable: false });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
75
88
|
export type TimeoutErrorInitObject = {
|
|
76
89
|
request: ApiErrorRequest;
|
|
77
90
|
preCallStack?: string;
|
|
@@ -126,6 +139,8 @@ export class TimeoutError extends Error {
|
|
|
126
139
|
this.request = initObject.request;
|
|
127
140
|
this.preCallStack = initObject.preCallStack;
|
|
128
141
|
|
|
142
|
+
hideProperties(this, ['request', 'preCallStack']);
|
|
143
|
+
|
|
129
144
|
this.message = `${initObject.request.method} ${initObject.request.url}: Timeout error`;
|
|
130
145
|
|
|
131
146
|
if (this.preCallStack) {
|
|
@@ -187,6 +202,8 @@ export class ApiError extends Error {
|
|
|
187
202
|
this.response = initObject.response;
|
|
188
203
|
this.preCallStack = initObject.preCallStack;
|
|
189
204
|
|
|
205
|
+
hideProperties(this, ['request', 'response', 'preCallStack']);
|
|
206
|
+
|
|
190
207
|
let message = `${initObject.request.method} ${initObject.request.url}: ${this.response.status} ${this.response.statusText}`;
|
|
191
208
|
|
|
192
209
|
if (this.errors.length > 0) {
|
package/src/request.ts
CHANGED
|
@@ -68,6 +68,36 @@ function headersToObject(headers: Headers): Record<string, string> {
|
|
|
68
68
|
return result;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Headers whose value must never end up inside an error object.
|
|
73
|
+
*
|
|
74
|
+
* Right now this client only ever sets one of them, but the list is the point:
|
|
75
|
+
* a header added here is redacted everywhere an error can reach.
|
|
76
|
+
*/
|
|
77
|
+
const SENSITIVE_HEADERS = ['authorization'];
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns a copy of the request headers with every sensitive value blanked out.
|
|
81
|
+
*
|
|
82
|
+
* Errors travel: they get logged, serialized, sent to error trackers, and — as
|
|
83
|
+
* we learned the hard way — occasionally echoed back to an HTTP client. The
|
|
84
|
+
* real headers are only ever handed to `fetch()`; what we keep on the error is
|
|
85
|
+
* this redacted copy.
|
|
86
|
+
*/
|
|
87
|
+
function redactHeaders(
|
|
88
|
+
headers: Record<string, string>,
|
|
89
|
+
): Record<string, string> {
|
|
90
|
+
return Object.fromEntries(
|
|
91
|
+
Object.entries(headers).map(([key, value]) =>
|
|
92
|
+
SENSITIVE_HEADERS.includes(key.toLowerCase())
|
|
93
|
+
? // The last 4 characters are enough to tell two tokens apart while
|
|
94
|
+
// debugging, and useless to whoever gets hold of the log.
|
|
95
|
+
[key, `[REDACTED, ending in ${value.slice(-4)}]`]
|
|
96
|
+
: [key, value],
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
71
101
|
function buildApiErrorInitObject(
|
|
72
102
|
method: string,
|
|
73
103
|
url: string,
|
|
@@ -191,6 +221,8 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
191
221
|
delete headers['user-agent'];
|
|
192
222
|
}
|
|
193
223
|
|
|
224
|
+
const redactedHeaders = redactHeaders(headers);
|
|
225
|
+
|
|
194
226
|
const baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
195
227
|
const body = options.body ? JSON.stringify(options.body, null, 2) : undefined;
|
|
196
228
|
|
|
@@ -206,7 +238,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
206
238
|
if (logLevel >= LogLevel.BASIC) {
|
|
207
239
|
log(`[${requestId}] ${options.method} ${url}`);
|
|
208
240
|
if (logLevel >= LogLevel.BODY_AND_HEADERS) {
|
|
209
|
-
for (const [key, value] of Object.entries(
|
|
241
|
+
for (const [key, value] of Object.entries(redactedHeaders)) {
|
|
210
242
|
log(`[${requestId}] ${key}: ${value}`);
|
|
211
243
|
}
|
|
212
244
|
}
|
|
@@ -215,6 +247,10 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
215
247
|
}
|
|
216
248
|
}
|
|
217
249
|
|
|
250
|
+
// Declared out here so that the `finally` below can always clear it: a timer
|
|
251
|
+
// left pending keeps Node's event loop alive for as long as it runs.
|
|
252
|
+
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
253
|
+
|
|
218
254
|
try {
|
|
219
255
|
const requestPromise = makeCancelablePromise(
|
|
220
256
|
fetchFn(url, {
|
|
@@ -224,14 +260,12 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
224
260
|
}),
|
|
225
261
|
);
|
|
226
262
|
|
|
227
|
-
|
|
263
|
+
timeoutId = setTimeout(() => {
|
|
228
264
|
requestPromise.cancel();
|
|
229
265
|
}, options.requestTimeout || 30000);
|
|
230
266
|
|
|
231
267
|
const response = await requestPromise;
|
|
232
268
|
|
|
233
|
-
clearTimeout(timeoutId);
|
|
234
|
-
|
|
235
269
|
const responseContentType = response.headers.get('Content-Type');
|
|
236
270
|
const invalidContentType =
|
|
237
271
|
responseContentType && !responseContentType.includes('application/json');
|
|
@@ -242,7 +276,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
242
276
|
buildApiErrorInitObject(
|
|
243
277
|
options.method,
|
|
244
278
|
url,
|
|
245
|
-
|
|
279
|
+
redactedHeaders,
|
|
246
280
|
options.body,
|
|
247
281
|
response,
|
|
248
282
|
undefined,
|
|
@@ -308,7 +342,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
308
342
|
buildApiErrorInitObjectFromJobResult(
|
|
309
343
|
options.method,
|
|
310
344
|
url,
|
|
311
|
-
|
|
345
|
+
redactedHeaders,
|
|
312
346
|
options.body,
|
|
313
347
|
jobResult.status,
|
|
314
348
|
jobResult.payload,
|
|
@@ -328,7 +362,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
328
362
|
buildApiErrorInitObject(
|
|
329
363
|
options.method,
|
|
330
364
|
url,
|
|
331
|
-
|
|
365
|
+
redactedHeaders,
|
|
332
366
|
options.body,
|
|
333
367
|
response,
|
|
334
368
|
responseBody,
|
|
@@ -373,7 +407,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
373
407
|
buildTimeoutErrorInitObject(
|
|
374
408
|
options.method,
|
|
375
409
|
url,
|
|
376
|
-
|
|
410
|
+
redactedHeaders,
|
|
377
411
|
options.body,
|
|
378
412
|
preCallStack,
|
|
379
413
|
),
|
|
@@ -381,5 +415,7 @@ export async function request<T>(options: RequestOptions): Promise<T> {
|
|
|
381
415
|
}
|
|
382
416
|
|
|
383
417
|
throw error;
|
|
418
|
+
} finally {
|
|
419
|
+
clearTimeout(timeoutId);
|
|
384
420
|
}
|
|
385
421
|
}
|