Nodejs HTTP retry on timeout or error

I am trying to automatically retry HTTP requests in timeout or error.
Currently my code is as follows:

var req = http.get(url, doStuff) .on('error', retry) .setTimeout(10000, retry); 

However, a single request can sometimes trigger both "upon error" and "timeout" events. What is the best way to implement retries?

+11
source share
4 answers

I searched the same and found an interesting requestretry module that is well suited for such a requirement.

Here is the usage:

 var request = require('requestretry') request({ url: myURL, json: true, maxAttempts: 5, // (default) try 5 times retryDelay: 5000, // (default) wait for 5s before trying again retrySrategy: request.RetryStrategies.HTTPOrNetworkError // (default) retry on 5xx or network errors }, function(err, response, body){ // this callback will only be called when the request succeeded or after maxAttempts or on error if (response) { console.log('The number of request attempts: ' + response.attempts); } }) 
+18
source

You can try something like this:

 function doRequest(url, callback) { var timer, req, sawResponse = false; req = http.get(url, callback) .on('error', function(err) { clearTimeout(timer); req.abort(); // prevent multiple execution of `callback` if error after // response if (!sawResponse) doRequest(url, callback); }).on('socket', function(sock) { timer = setTimeout(function() { req.abort(); doRequest(url, callback); }, 10000); }).once('response', function(res) { sawResponse = true; clearTimeout(timer); }); } 

UPDATE: In recent / modern versions of node, you can now specify the timeout option (measured in milliseconds), which sets the socket timeout (before connecting the socket). For instance:

 http.get({ host: 'example.org', path: '/foo', timeout: 5000 }, (res) => { // ... }); 
+5
source

This was the code that worked for me. The key was to destroy the socket after a timeout, and also verify that the response is complete.

 function httpGet(url, callback) { var retry = function(e) { console.log("Got error: " + e.message); httpGet(url, callback); //retry } var req = http.get(url, function(res) { var body = new Buffer(0); res.on('data', function (chunk) { body = Buffer.concat([body, chunk]); }); res.on('end', function () { if(this.complete) callback(body); else retry({message: "Incomplete response"}); }); }).on('error', retry) .setTimeout(20000, function(thing){ this.socket.destroy(); }); } 
+1
source

Using the Request promise, why not just use the while loop inside the asynchronous anonymous function:

 (async () => { var download_success = false; while (!download_success) { await requestpromise(options) .then(function (response) { download_success = true; console.log('Download SUCCESS'); }) .catch(function (err) { console.log('Error downloading : ${err.message}'); }); } })(); 

Also note that the requestretry module exists.

0
source

Source: https://habr.com/ru/post/976183/


All Articles