Skip to content

Commit b650f7f

Browse files
jdelbickbadvisiontmathern
authored
BUGFIX-RELEASE: more robust handling of http errors to fix dep mod tests (#62)
* add test case for timeout * more robust handling of http errors to fix dep mod tests * Apply suggestions from code review Co-authored-by: tmathern <60901087+tmathern@users.noreply.github.com> Co-authored-by: Brendan Robert <brendan.robert@gmail.com> Co-authored-by: tmathern <60901087+tmathern@users.noreply.github.com>
1 parent 587eb64 commit b650f7f

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ function checkParameters(retryOptions) {
134134
}
135135
}
136136

137+
/**
138+
* Format HTTP error response into response object
139+
* @param {Object} error
140+
* @returns
141+
*/
142+
function getResponseFromHttpError(error) {
143+
let code = error.code;
144+
if (!code || typeof(code) !== 'number') {
145+
console.warn(`error code is invalid ${code}. Setting status code to 500`);
146+
code = 500;
147+
}
148+
return {status: code, statusMessage : error.message || "Unknown server error"};
149+
}
150+
137151
/**
138152
* @typedef {Object} RetryOptions options for retry or false if want to disable retry
139153
* @property {Integer} retryMaxDuration time (in milliseconds) to retry until throwing an error
@@ -189,7 +203,7 @@ module.exports = async function (url, options) {
189203
return resolve(response);
190204
}
191205
} catch (error) {
192-
const response = {status: error.code || 500, statusMessage : error.message || "Unknown server error"};
206+
const response = getResponseFromHttpError(error);
193207
if (!shouldRetry(retryOptions, error, response, waitTime)) {
194208
if (error.name === 'AbortError') {
195209
return reject(new FetchError(`network timeout at ${url}`, 'request-timeout'));

test/index.test.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,28 @@ describe('test fetch retry', () => {
320320
assert.strictEqual(response.statusText, 'OK');
321321
assert.strictEqual(response.status, 200);
322322
});
323+
it('test get retry with default settings invalid error code then 200 with auth headers set', async () => {
324+
nock(FAKE_BASE_URL)
325+
.get(FAKE_PATH)
326+
.matchHeader('Authorization', 'Basic thisShouldBeAnAuthHeader')
327+
.twice()
328+
.replyWithError({
329+
message: 'something awful happened',
330+
code: 'INVALID ERROR CODE',
331+
});
332+
nock(FAKE_BASE_URL)
333+
.get(FAKE_PATH)
334+
.matchHeader('Authorization', 'Basic thisShouldBeAnAuthHeader')
335+
.reply(200, { ok: true });
336+
const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`,
337+
{
338+
method: 'GET', headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' }
339+
});
340+
assert(nock.isDone());
341+
assert(response.ok);
342+
assert.strictEqual(response.statusText, 'OK');
343+
assert.strictEqual(response.status, 200);
344+
});
323345

324346
it('test retry with default settings 400', async () => {
325347
nock(FAKE_BASE_URL)
@@ -391,6 +413,32 @@ describe('test fetch retry', () => {
391413
console.log(`ellapsed: ${timer.ellapsed}`);
392414
assert.ok(timer.isBetween(300, 500), "Should have taken approximately 400ms");
393415
});
416+
it('test network timeout', async () => {
417+
nock(FAKE_BASE_URL)
418+
.get(FAKE_PATH)
419+
.once()
420+
.replyWithError({
421+
message: 'something awful happened',
422+
code: '503',
423+
});
424+
const timer = new Timer();
425+
try {
426+
await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET', retryOptions: { retryMaxDuration: 2 } });
427+
assert.fail("Should have thrown an error!");
428+
} catch (e) {
429+
assert(e.message.includes("network timeout"));
430+
assert(e.type === "request-timeout");
431+
}
432+
console.log(`ellapsed: ${timer.ellapsed}`);
433+
assert.ok(timer.isBetween(1, 100), "Should have taken approximately 10ms");
434+
});
435+
it('test network timeout 200', async () => {
436+
nock(FAKE_BASE_URL)
437+
.put(FAKE_PATH, 'hello')
438+
.reply(200, { ok: true });
439+
const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'PUT', body: 'hello', retryOptions: { retryMaxDuration: 1000 } });
440+
assert.strictEqual(response.ok, true);
441+
});
394442

395443
it('test retry timeout on 404 response', async () => {
396444
nock(FAKE_BASE_URL)

0 commit comments

Comments
 (0)