Retrying Failed HTTP Requests in Node.js

Relying on 3rd party services to handle some part of your business logic is a common practice. You might use SendGrid to send emails, Google Cloud Bucket Storage api to store some binary blob or Twilio for sending SMS to your users.

Although, the three I mentioned above are quite reliable, you might find yourself in a situration where any of these thre or the external resource you are relying on rejects your request with the dreaded 503 Serice Unavailable message.

Assuming everything is good on your side, you might want to retry that HTTP API request.

This is how you do that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const https = require('https');
const RETRY_THRESHOLD = 3;
let retryCount = 1;

const httpRequest = (options, callback) => {
let buffer = new Buffer(0);

const retryRequest = error => {
console.log(`Rejection: ${retryCount}`, error);

if (retryCount === RETRY_THRESHOLD) {
return new Error(error);
}

retryCount++;

const TWO_SECS = 2000;

// Waiting 2 secs before sending another request
setTimeout(() => {
httpRequest(options);
}, TWO_SECS);
}

const request = https.request(options, response => {
const responseInstance = response
.on('error', error => {
responseInstance.abort();

retryRequest(error);
})
.on('data', chunk => Buffer.concat([buffer, chunk]))
.on('end', () => {
// Only for response type = json
responseBody = JSON.parse(responseBody);

// You an also check for `responseBody.statusCode === 503`
// to be more specific
// for your retries
if (!responseBody.ok) {
// retry http request here

retryRequest(error);
}
});

// Avoids socket hangups
responseInstance.end();
});
}

You can call this function as the standard https request in node.js,

1
2
3
4
5
6
7
httpRequest({
host: 'www.googleapis.com',
protocol: 'https',
port: 443, // For https
path: '/storage/v1/b/my-bucket',
method: 'GET',
});

The function will retry itself after failure three times before giving up.

Of course, this is just for your knowledge. In real life, you should probably use a well known package for this kind of stuff. I’d recommend one of these: