Skip to content

Commit 99776e6

Browse files
janpieterzDanny McCormick
authored andcommitted
Retry http 502, 503, 504 status codes (#39)
* Retry http 502, 503, 504 status codes * Implement requested changes * Fix types, +1's and add unit test (commented) * Fix nit missing semi colon * Add unit tests for retries * Up version to 0.10.2 * Enable unit tests
1 parent 7820a4a commit 99776e6

File tree

5 files changed

+64
-6
lines changed

5 files changed

+64
-6
lines changed

make.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ target.units = function () {
162162
target.test = function () {
163163
target.build();
164164

165-
console.log("-------Unit Tests-------");
166-
run('tsc -p ./test/units --outDir ' + unitPath, true);
165+
target.units();
167166

168167
console.log("-------Other Tests-------");
169168
run('tsc -p ./test/tests --outDir ' + testPath, true);

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "azure-pipelines-tool-lib",
3-
"version": "0.10.1",
3+
"version": "0.10.2",
44
"description": "Azure Pipelines Tool Installer Lib for CI/CD Tasks",
55
"main": "tool.js",
66
"scripts": {

test/units/toolTests.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,4 +428,48 @@ describe('Tool Tests', function () {
428428
}
429429
});
430430
});
431+
432+
it("works with a 502 temporary failure", async function() {
433+
this.timeout(5000);
434+
nock('http://microsoft.com')
435+
.get('/temp502')
436+
.twice()
437+
.reply(502, undefined);
438+
nock('http://microsoft.com')
439+
.get('/temp502')
440+
.reply(200, undefined);
441+
442+
return new Promise<void>(async (resolve, reject) => {
443+
try {
444+
let statusCodeUrl: string = "http://microsoft.com/temp502";
445+
let downPath: string = await toolLib.downloadTool(statusCodeUrl);
446+
447+
resolve();
448+
} catch (err) {
449+
reject(err);
450+
}
451+
});
452+
});
453+
454+
it("doesn't retry 502s more than 3 times", async function() {
455+
this.timeout(5000);
456+
nock('http://microsoft.com')
457+
.get('/perm502')
458+
.times(3)
459+
.reply(502, undefined);
460+
461+
return new Promise<void>(async (resolve, reject) => {
462+
try {
463+
let statusCodeUrl: string = "http://microsoft.com/perm502";
464+
let downPath: string = await toolLib.downloadTool(statusCodeUrl);
465+
466+
reject('Shouldnt have succeeded');
467+
} catch (err) {
468+
if (err['httpStatusCode'] && err['httpStatusCode'] == 502) {
469+
resolve();
470+
}
471+
reject(err);
472+
}
473+
});
474+
});
431475
});

tool.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ export function prependPath(toolPath: string) {
4545
console.log('##vso[task.prependpath]' + toolPath);
4646
}
4747

48+
function delay(ms: number) {
49+
return new Promise(resolve => setTimeout(resolve, ms));
50+
}
51+
4852
//-----------------------------
4953
// Version Functions
5054
//-----------------------------
@@ -217,10 +221,21 @@ export async function downloadTool(url: string, fileName?: string): Promise<stri
217221
if (fs.existsSync(destPath)) {
218222
throw new Error("Destination file path already exists");
219223
}
220-
221-
// TODO: retries
224+
222225
tl.debug('downloading');
226+
const statusCodesToRetry = [httpm.HttpCodes.BadGateway, httpm.HttpCodes.ServiceUnavailable, httpm.HttpCodes.GatewayTimeout];
227+
let retryCount: number = 1;
228+
const maxRetries: number = 3;
223229
let response: httpm.HttpClientResponse = await http.get(url);
230+
231+
while(retryCount < maxRetries && statusCodesToRetry.indexOf(response.message.statusCode) > -1) {
232+
tl.debug(`Download attempt "${retryCount}" of "${maxRetries}" failed with status code "${response.message.statusCode}".`);
233+
retryCount += 1;
234+
await delay(1000);
235+
tl.debug(`Downloading attempt "${retryCount}" of "${maxRetries}"`);
236+
response = await http.get(url);
237+
}
238+
224239
if (response.message.statusCode != 200) {
225240
let err: Error = new Error('Unexpected HTTP response: ' + response.message.statusCode);
226241
err['httpStatusCode'] = response.message.statusCode;

0 commit comments

Comments
 (0)