Skip to content

Commit

Permalink
Fixes #2888 - Retry on network error (#4959)
Browse files Browse the repository at this point in the history
* Fixes #2888 - Retry on network error

Retry failed network requests 3 times in the JS bindings like Ruby.
The previous 15 ms timeout was kept though, unlike the 2s sleep from Ruby.
Credit goes to @JosephGarrone for the workaround and @p0deje for finding the
Ruby http module.
  • Loading branch information
seanpoulter authored and jleyba committed Oct 29, 2017
1 parent 825ff9f commit 83bdd7b
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions javascript/node/selenium-webdriver/http/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ class HttpClient {
* @param {function(!Error)} onError The function to call if the request fails.
* @param {?string=} opt_data The data to send with the request.
* @param {?RequestOptions=} opt_proxy The proxy server to use for the request.
* @param {number=} opt_retries The current number of retries.
*/
function sendRequest(options, onOk, onError, opt_data, opt_proxy) {
function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
var hostname = options.hostname;
var port = options.port;

Expand All @@ -161,7 +162,7 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy) {
// An HTTP/1.1 proxy MUST ensure that any request message it forwards does
// contain an appropriate Host header field that identifies the service
// being requested by the proxy.
let targetHost = options.hostname
let targetHost = options.hostname;
if (options.port) {
targetHost += ':' + options.port;
}
Expand Down Expand Up @@ -226,9 +227,14 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy) {
});

request.on('error', function(e) {
if (e.code === 'ECONNRESET') {
if (typeof opt_retries === 'undefined') {
opt_retries = 0;
}

if (shouldRetryRequest(opt_retries, e)) {
opt_retries += 1;
setTimeout(function() {
sendRequest(options, onOk, onError, opt_data, opt_proxy);
sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries);
}, 15);
} else {
var message = e.message;
Expand All @@ -247,6 +253,36 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy) {
}


const MAX_RETRIES = 3;

/**
* A retry is sometimes needed on Windows where we may quickly run out of
* ephemeral ports. A more robust solution is bumping the MaxUserPort setting
* as described here: http://msdn.microsoft.com/en-us/library/aa560610%28v=bts.20%29.aspx
*
* @param {!number} retries
* @param {!Error} err
* @return {boolean}
*/
function shouldRetryRequest(retries, err) {
return retries < MAX_RETRIES && isRetryableNetworkError(err);
}

/**
* @param {!Error} err
* @return {boolean}
*/
function isRetryableNetworkError(err) {
if (err && err.code) {
return err.code === 'ECONNABORTED' ||
err.code === 'ECONNRESET' ||
err.code === 'EADDRINUSE';
}

return false;
}


// PUBLIC API

exports.Executor = httpLib.Executor;
Expand Down

0 comments on commit 83bdd7b

Please sign in to comment.