How to avoid a NodeJS ECONNRESET error? - node.js

I have an app running which is doing every 20 to 30 minutes a http.request. When I do these requests every 10 seconds or so, it works just fine, but when there is a gap of 30 minutes between the requests, I get the following error message.
{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }
Now I think, this is a timeout error. The connection dies in the background and when the next request take place, it throws this error since the connection is dead.
My idea now is to close the connection after each request and re-establisch the connection on every new request. But I have no idea how to accomplish this in NodeJS.
UPDATE
I found out that the problem appears, when I first GET than POST and again GET.
Here ist the code for GET and POST
https.request({ method: 'GET'..., function(res) {
}).on('error', function(e) {
throw 'error';
}).end();
var request = https.request({ method: 'POST'..., function(res) {
}).on('error', function(e) {
throw 'error';
});
request.write(query);
request.end();

Related

syscall: 'write', code: 'EPROTO', errno: -4046, or AxiosError: read ECONNRESET

I am trying to test out using proxies for the first time in my coding career and been trying for a while now. However I keep getting this weird error that doesnt make any sense in my head. The proxy I use here is taken from http://free-proxy.cz/en/proxylist/country/US/https/date/all. I have no problem paying for some proxy servers I just wanna make sure it works before paying for anything.
However I keep getting the error AxiosError: read ECONNRESET OR AxiosError: Client network socket disconnected before secure TLS connection was established OR write EPROTO E0DA0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:355:
I am running the code on Localhost so my connection to the proxy server is not https.
Here is the code I am trying to excecute. I have imported
var HttpsProxyAgent = require('https-proxy-agent');
But this clearly is not the problem.
router.get("/userInvTest", async (req, res) => {
try {
const axiosDefaultConfig = {
proxy: false,
httpsAgent: new HttpsProxyAgent('https://205.134.235.132:3129'),
};
const axiosUse = require('axios').create(axiosDefaultConfig);
const steamInventory = await axiosUse.get("https://steamcommunity.com/inventory/76561198027016127/730/2?l=english&count=5000");
console.log(steamInventory.data)
res.status(200).send(steamInventory.data)
} catch (err) {
console.log(err)
}
})

What could cause "connect ETIMEDOUT" error when the URL is working in browser?

I train myslef with NodeJS and tried a simple GET call.
Here is my code:
var http = require('http');
var options = {
host: 'www.boardgamegeek.com',
path: '/xmlapi/boardgame/1?stats=1',
method: 'GET'
}
var request = http.request(options, function (response) {
var str = ""
response.on('data', function (data) {
str += data;
});
response.on('end', function () {
console.log(str);
});
});
request.on('error', function (e) {
console.log('Problem with request: ' + e.message);
});
request.end();
The URL called seems to work in my browser https://www.boardgamegeek.com/xmlapi/boardgame/1?stats=1
Anyway, I've got Problem with request: connect ETIMEDOUT when I run the code and I have no idea how to fix it.
What could cause this error ? Is it my code or is it a network/proxy issue?
When behind a proxy you need to make the following modifications (as explained in this answer):
put the proxy host in the host parameter
put the proxy port in the port parameter
put the full destination URL in the path parameter :
Which gives:
var options = {
host: '<PROXY_HOST>',
port: '<PROXY_PORT>',
path: 'http://www.boardgamegeek.com/xmlapi/boardgame/1?stats=1',
method: 'GET',
headers: {
Host: 'www.boardgamegeek.com'
}
}
In my case it was because of http but not https as required
If this error occurs while using POSTMAN.
So, when you call a request in Postman and the API requires your VPN to be up before you can make a successful call. You will need to connect or reconnect your VPN.
In my case, I was working on a company's laptop. I found out it was the VPN that was down.
The following change with the request worked for me:
var options = {
proxy:'PROXY URL',
uri: 'API URL',
method: 'GET'
}
request(options, function (err, response, body) {
if(err){
console.log('error:', err);
} else {
console.log('body:', body);
}
});
In my case it was a misconfigured subnet. Only one of the 2 subnets in the ELB worked. But my client kept trying to connect to the misconfigured one.
if you have URL
like :
URL: 'localhost:3030/integration',
The URL above cause some issues because HTTP does not exist at the beginning of URL so Just change it to it should work.
URL: 'http://localhost:3030/integration',
In my case, I was getting this error because the request body of my post api was very large.
I was facing this issue on Ubuntu Server while maintaining a node instance on PM2. Basically after restarting the instance after taking the pull I was getting the same error on initial connection of mySQL inside the code.
Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/home/deam_server/node_modules/mysql/lib/Connection.js:419:13)
at Object.onceWrapper (events.js:275:13)
at Socket.emit (events.js:182:13)
at Socket.EventEmitter.emit (domain.js:442:20)
at Socket._onTimeout (net.js:447:8)
at ontimeout (timers.js:427:11)
at tryOnTimeout (timers.js:289:5)
at listOnTimeout (timers.js:252:5)
at Timer.processTimers (timers.js:212:10)
Though the same code was running perfectly on my local machine.
After that I used "df" command which helped me to realise that my root directory was 100% occupied. I allotted some memory to the root directory and the restarted the node instance and then it started working fine.
Sometimes it can simply be because your internet is down.

How to recover from Node.js request pipe with ECONNRESET error?

My site is all in HTTPS. When I show some pictures from other non-HTTPS sites, I rewrite the request from my server and pipe the response to the client as follows.
request.get(imageUrl)
.on('response', function(response) {})
.on('error', function(err) {
console.log(err);
}).pipe(res);
Sometimes it throws the error of
{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }.
So how can I recover from the error to make my site continue to serve?

Nodejs HTTPS client timeout not closing TCP connection

I need to close http connection if they take longer than 3s, so this is my code:
var options = {
host: 'google.com',
port: '81',
path: ''
};
callback = function(response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
response.on('error', function () {
console.log('ERROR!');
});
}
var req = https.request(options, callback);
req.on('socket', function(socket) {
socket.setTimeout(3000);
socket.on('timeout', function() {
console.log('Call timed out!');
req.abort();
//req.end();
//req.destroy();
});
});
req.on('error', function(err) {
console.log('REQUEST ERROR');
console.dir(err);
req.abort();
//req.end();
});
req.end();
This is what I get after 3s:
Call timed out!
REQUEST ERROR
{ [Error: socket hang up] code: 'ECONNRESET' }
Using a watch on lsof | grep TCP | wc -l I can see that the TCP connection remains open, even after receiving the 'timeout' event.
After an eternity, I get this and the connection is closed:
REQUEST ERROR
{ [Error: connect ETIMEDOUT] code: 'ETIMEDOUT', errno: 'ETIMEDOUT', syscall: 'connect' }
Does anyone know why this is happening? Why does calling req.abort() or req.end() or req.destory() not close the connection? Is it because I'm setting the timeout on the socket instead of the actual HTTP call? If yes, how do I close the connection?
you need to set the timeout on the connection:
req.connection.setTimeout(3000);
This timeout will change the socket status from ESTABLISHED to FIN_WAIT1 and FIN_WAIT2.
In Ubuntu there is a default timeout of 60 seconds for FIN_WAIT socket status, so the total time for the socket to close is 63 seconds if it doesn't receive any traffic. If the sockets receive traffic, the timeouts will start over.
If you need to close the socket within 3 seconds, I guess you have to set the connection timeout to 3000ms and lower the kernel tcp fin wait timeout.

socket hanging and node crashing

I have a node app that posts data to remote apis and fetches the responses. It works fine but at times the node server crashes and generates the following errror:
events.js:71
throw arguments[1]; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (http.js:1264:15)
at Socket.socketCloseListener (http.js:1315:23)
at Socket.EventEmitter.emit (events.js:126:20)
at Socket._destroy.destroyed (net.js:358:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
I googled and found that it happens due to some timeout thing but i am not really sure as to how to overcome this.
Here is the required code in my server.js:
if(request.body.company=="CQ")
{
var postData={firstName:request.body.firstname,lastName:request.body.lastname,Email:request.body.email,DayPhoneNumber:request.body.daytimePhone,Address1:request.body.addressOne,city:request.body.city,state:request.body.State,postalCode:request.body.zip,AreaOfIntrest:request.body.areaOfInterest,VendorLocationId:"38404",Notes:request.body.Notes,GraduationYear:request.body.graduationYear,AffiliateLocationId:"12345",LocationId:"12345",CampaignId:"12345"};
var options={hostname:'webservices.someapi.com', path:'/ILM/Default.ashx?'+qs.stringify(postData), method:'GET'};
var req = http.request(options, function(res) {
res.on('data', function (chunk) {
edModel.find({$and:[{daytimePhone:request.body.daytimePhone},{company:"CQ"}]},function(err,count){
if(count.length==0)
{
var sr='RESPONSE: ' + chunk;
if(sr.indexOf('status="Error"')==-1)
{
request.body.leadid=sr;
var sr=sr.slice(sr.indexOf("leadid"));
sr=sr.slice(0,sr.indexOf(">"));
edDoc=new edModel(request.body);
edDoc.save();
response.send({response:sr});
}
else
{
response.send({response:sr});
}
}
else
{
response.send({response:"<span style='color:red'>Duplicate Lead.<br> A lead with this number already exists in our database</span>"});
}
});
});
});
// write data to request body
req.write('data\n');
req.end();
}
I have several such if else conditions in the server.js file.
in node 0.8.20 there was a bug about that problem. try using http.get instead of http.request. or just dont use 0.8.20 if you use that version.

Resources