Viewed   4.7k times

I have a simple Node.js bot that makes an HTTP request each second to a rest API.

If the returned data is right then I construct an URL where I HTTP POST.

Everything works alright but after ~4-5hrs of running I got this error

0|server   | error:  Error: getaddrinfo ENOTFOUND www.rest-api.com www.rest-api.com:443
0|server   |     at errnoException (dns.js:28:10)
0|server   |     at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:73:26)

Can someone explain to me why this has happened?

After I restart my server everything got working.

I'm using axios to make the http requests.

 Answers

5

I met the same issue and solved it!

try:

sudo vi /etc/hosts

and add:

127.0.0.1 localhost

to hosts

Wednesday, August 24, 2022
1

Actually, I believe the previously accepted answer has some flaws, as it will not handle the writestream properly, so if you call "then()" after Axios has given you the response, you will end up having a partially downloaded file.

This is a more appropriate solution when downloading slightly larger files:

export async function downloadFile(fileUrl: string, outputLocationPath: string) {
  const writer = createWriteStream(outputLocationPath);

  return Axios({
    method: 'get',
    url: fileUrl,
    responseType: 'stream',
  }).then(response => {

    //ensure that the user can call `then()` only when the file has
    //been downloaded entirely.

    return new Promise((resolve, reject) => {
      response.data.pipe(writer);
      let error = null;
      writer.on('error', err => {
        error = err;
        writer.close();
        reject(err);
      });
      writer.on('close', () => {
        if (!error) {
          resolve(true);
        }
        //no need to call the reject here, as it will have been called in the
        //'error' stream;
      });
    });
  });
}

This way, you can call downloadFile(), call then() on the returned promise, and making sure that the downloaded file will have completed processing.

Or, if you use a more modern version of NodeJS, you can try this instead:

import * as stream from 'stream';
import { promisify } from 'util';

const finished = promisify(stream.finished);

export async function downloadFile(fileUrl: string, outputLocationPath: string): Promise<any> {
  const writer = createWriteStream(outputLocationPath);
  return Axios({
    method: 'get',
    url: fileUrl,
    responseType: 'stream',
  }).then(async response => {
    response.data.pipe(writer);
    return finished(writer); //this is a Promise
  });
}
Friday, October 7, 2022
 
3

You just need to handle the error event, as stated in the error message. According to the documentation:

If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an 'error' event is emitted on the returned request object.

Here is a usage example:

var getRequest = _http.get(options, function(res) {
    // …
});
getRequest.on('error', function (err) {
    console.log(err);
});

which yields:

$ node test.js
{ [Error: getaddrinfo ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'getaddrinfo' }
Tuesday, August 30, 2022
 
4

The issue was in the headers. When using form-data, you have to make sure to pass the headers generated by it to Axios. Answer was found here

headers: bodyData.getHeaders()

Working code is:

const fs = require('fs');
const FormData = require('form-data');
const Axios = require('axios').default;

let file = '/tmp/the-test.png';
var bodyData = new FormData();
let b = fs.readFileSync(file, { encoding: 'base64' });
bodyData.append('image', b);
Axios({
  method  : 'post',
  url     : 'https://api.imgbb.com/1/upload?key=myapikey',
  headers : bodyData.getHeaders(),
  data    : bodyData
})
  .then((resolve) => {
    console.log(resolve.data);
  })
  .catch((error) => console.log(error.response.data));
Thursday, October 13, 2022
2

I modified your code to work correctly in AWS Lambda Node.js 6.10. I set the Lambda timeout to be 60 seconds for testing.

The big change is adding "res.on('data', function(chunk) {}:" and "res.on('end', function() {}".

var https = require('https');
exports.handler = (event, context, callback) => {
    var params = {
        host: "bittrex.com",
        path: "/api/v1.1/public/getmarketsummaries"
    };
    var req = https.request(params, function(res) {
        let data = '';
        console.log('STATUS: ' + res.statusCode);
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
            data += chunk;
        });
        res.on('end', function() {
            console.log("DONE");
            console.log(JSON.parse(data));
        });
    });
    req.end();
};
Tuesday, October 18, 2022
 
989
 
989
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :