Skip to content

Commit fa18cb0

Browse files
authored
Merge pull request #51 from saksham-gg/master
FORCE-3955 error handling improvements
2 parents 9f71d7a + 0bd6193 commit fa18cb0

File tree

4 files changed

+803
-3288
lines changed

4 files changed

+803
-3288
lines changed

lib/cfg/node-tunnel-config-v3-latest.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
},
7777
"AuthUrl": "https://accounts.lambdatest.com/api/user/token/auth",
7878
"logEnable": true,
79-
"latest": "4.0.7",
79+
"latest": "4.0.8",
8080
"supportedVersions":
8181
[
8282
"1.0.0",
@@ -120,6 +120,7 @@
120120
"4.0.4",
121121
"4.0.5",
122122
"4.0.6",
123-
"4.0.7"
123+
"4.0.7",
124+
"4.0.8"
124125
]
125126
}

lib/tunnel.js

Lines changed: 100 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -412,81 +412,128 @@ function runBinary_(self, retries, fnCallback) {
412412
}
413413

414414
/**
415-
* verifyToken_ is used to Run Tunnel Binary
416-
* @param {Setting} options passed User argumants.
415+
* verifyToken_ is used to verify user credentials by sending a POST request to the authentication server with retries and exponential backoff.
416+
* @param {Setting} options passed User arguments.
417417
* @param {Function} fnCallback is a Callable function.
418418
* @return {Object|Error} Return User Object or Error if any.
419419
*/
420-
function verifyToken_(options, fnCallback) {
421-
try {
422-
var data = JSON.stringify({
423-
username: options['user'],
424-
token: options['key']
425-
});
420+
function verifyToken_(options, fnCallback, retries = 3, delay = 1000) {
421+
const attempt = () => {
422+
try {
423+
var data = JSON.stringify({
424+
username: options['user'],
425+
token: options['key']
426+
});
427+
428+
var _httpAuthUrl = urlParse.parse(httpTunnelConfig.jsonResponse.AuthUrl);
429+
var reqOptions = {
430+
hostname: _httpAuthUrl.hostname,
431+
port: _httpAuthUrl.port,
432+
path: _httpAuthUrl.path,
433+
method: 'POST',
434+
headers: {
435+
'Content-Type': 'application/json',
436+
'Content-Length': data.length,
437+
Accept: 'application/json',
438+
client: 'npm-tunnel',
439+
version: packageVersion
440+
}
441+
};
426442

427-
var _httpAuthUrl = urlParse.parse(httpTunnelConfig.jsonResponse.AuthUrl);
428-
var reqOptions = {
429-
hostname: _httpAuthUrl.hostname,
430-
port: _httpAuthUrl.port,
431-
path: _httpAuthUrl.path,
432-
method: 'POST',
433-
headers: {
434-
'Content-Type': 'application/json',
435-
'Content-Length': data.length,
436-
Accept: 'application/json',
437-
client: 'npm-tunnel',
438-
version: packageVersion
443+
var proxyOpts = util.getProxyOpts_(options);
444+
if (Object.keys(proxyOpts).length) {
445+
reqOptions.agent = new HttpsProxyAgent(proxyOpts);
439446
}
440-
};
441-
var proxyOpts = util.getProxyOpts_(options);
442-
if (Object.keys(proxyOpts).length) {
443-
reqOptions.agent = new HttpsProxyAgent(proxyOpts);
444-
}
445-
var req = https.request(reqOptions, resp => {
446-
let json = '';
447-
resp.on('data', chunk => {
448-
json += chunk;
447+
448+
var req = https.request(reqOptions, resp => {
449+
let json = '';
450+
resp.on('data', chunk => {
451+
json += chunk;
452+
});
453+
resp.on('end', () => {
454+
try {
455+
if (resp.statusCode >= 500) {
456+
throw new Error(`Server error with status code: ${resp.statusCode}`);
457+
}
458+
if (typeof json === 'string') {
459+
json = JSON.parse(json);
460+
}
461+
if (json && json.type === 'error') {
462+
logger.log(
463+
options['user'],
464+
options['key'],
465+
{ filename: __filename },
466+
options,
467+
'Authentication failed: ' + json.message
468+
);
469+
throw new Error(json.message);
470+
}
471+
return fnCallback(false, json);
472+
} catch (parseError) {
473+
if (retries > 0) {
474+
logger.log(
475+
options['user'],
476+
options['key'],
477+
{ filename: __filename },
478+
options,
479+
`Parse or server error on attempt ${4 - retries}, retrying... Error: ` + parseError
480+
);
481+
setTimeout(() => {
482+
verifyToken_(options, fnCallback, retries - 1, delay * 2);
483+
}, delay);
484+
} else {
485+
logger.log(
486+
options['user'],
487+
options['key'],
488+
{ filename: __filename },
489+
options,
490+
'Parse or server error, maximum retries reached. Error: ' + parseError
491+
);
492+
return fnCallback(true, parseError);
493+
}
494+
}
495+
});
449496
});
450-
resp.on('end', () => {
451-
if (typeof json === 'string') {
452-
json = JSON.parse(json);
453-
}
454-
if (json && json.type === 'error') {
497+
498+
req.on('error', e => {
499+
if (e.code === 'ECONNRESET' || e.code === 'ENOTFOUND' || e.code === 'ETIMEDOUT' || retries > 0) {
455500
logger.log(
456501
options['user'],
457502
options['key'],
458503
{ filename: __filename },
459504
options,
460-
'Getting this issue while user is not valid' + json
505+
`Network error on attempt ${4 - retries}, retrying... Error: ` + e
461506
);
462-
return fnCallback(true, json);
507+
setTimeout(() => {
508+
verifyToken_(options, fnCallback, retries - 1, delay * 2);
509+
}, delay);
510+
} else {
511+
logger.log(
512+
options['user'],
513+
options['key'],
514+
{ filename: __filename },
515+
options,
516+
'Network error, maximum retries reached. Error: ' + e
517+
);
518+
return fnCallback(true, e);
463519
}
464-
return fnCallback(false, json);
465520
});
466-
});
467521

468-
req.on('error', e => {
522+
req.write(data);
523+
req.end();
524+
} catch (e) {
469525
logger.log(
470526
options['user'],
471527
options['key'],
472528
{ filename: __filename },
473529
options,
474-
'We are getting this error while verifying user and key validity. Error : ' + e
530+
'Something unexpected while setting up the request. Error : ' + e
475531
);
476532
return fnCallback(true, e);
477-
});
478-
req.write(data);
479-
req.end();
480-
} catch (e) {
481-
logger.log(
482-
options['user'],
483-
options['key'],
484-
{ filename: __filename },
485-
options,
486-
'Something unexpected while verifying the user and key validity. Error : ' + e
487-
);
488-
return fnCallback(true, e);
489-
}
533+
}
534+
};
535+
536+
attempt();
490537
}
491538

492539
/**

0 commit comments

Comments
 (0)