0

I have code like this:

const https = require('https');

const request = async (data, options) => {
  return new Promise((resolve, reject) => {
    const req = https.request(options, function(res) {
      const chunks = [];

      res.on('data', function(chunk) {
        chunks.push(Buffer.from(chunk));
      });

      res.on('end', function() {
        let body = Buffer.concat(chunks);

        body = body.toString();

        resolve(body);
      });
    });

    if (data) {
      req.write(JSON.stringify(data));
    }

    // this never fires, tried after comment below
    req.on('timeout', () => {
      console.log("This timed out")
    })

    // handle connection errors
    req.on('error', reject);
    req.end();
  });
};

async function run() {
  try {
    const response = await request(null, {
      method: 'GET',
      hostname: 'example.com',
      timeout: 1,
      path: '/',
      headers: {
        'Content-Type': 'application/json'
      }
    });
    console.log(response);
  } catch (e) {
    console.log(e);
  }
}



run();

The docs at https://nodejs.org/api/http.html#http_http_request_options_callback say this about timeout:

A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected.

My call is obviously going to take more than 1MS, yet I am not getting any errors thrown. What am I missing here?

Update

I am able to get req.on('timeout' to work when I am using http module rather than https. Not sure why that would be different? I literally can change require('https') to require('http') and see everything work as expected. The docs say options should be identical, but with different defaults.

Dave Stein
  • 8,653
  • 13
  • 56
  • 104
  • Doesn't it throw a `"timeout"` event? Also, it may not be what you think it is--this is the connect timeout. Do you actually want a *request* timeout? – Dave Newton Mar 06 '20 at 21:46
  • Ah yeah I see I am misreading and you are right. I didn't see anything for a request timeout though? – Dave Stein Mar 06 '20 at 22:01
  • Do I just need to set my own setTimeout to throw an error if I haven't gotten a response? And clear the timeout on success of the request to not accidentally throw? Would that be it? – Dave Stein Mar 06 '20 at 22:02
  • Request time-out is one of the “options” object properties, iirc. – Dave Newton Mar 07 '20 at 00:54
  • Are you using the `request` module or `request-promise` module. Because if it's the `request` module, then it doesn't return a promise and thus you won't catch a timeout with `try/catch`. You would have to catch it with `req.on('timeout', ...)`. – jfriend00 Mar 07 '20 at 01:06
  • Hey. I realize I pasted something confusing. My “request” method wraps https.request and makes a promise work. How can I define a time-out time for req.on(‘timeout’? The options I’m using are just being passed through to the native https.request method. – Dave Stein Mar 08 '20 at 16:00
  • Oh wait... so you’re saying I need to use the timeout option AND handle the event. I will give that a try when I’m at work next :) – Dave Stein Mar 08 '20 at 16:02
  • @jfriend00 i updated the code block to show what i'm using... and `req.on('timeout')` did not work. Sorry it took me a minute - was on PTO and messaging from phone yesterday. – Dave Stein Mar 10 '20 at 14:26
  • @DaveStein I tested it using `https` on `node 13.10.1` and `node 10.19.0` and it works for me, `timeout` event triggers and it prints `"This timed out"`. – Christos Lytras Mar 12 '20 at 01:18

1 Answers1

0

Your exact code with require('https') runs properly on Node.js 10, 12 and 13 on macOS Catalina with nvm. I get the following console log:

This timed out
{"error_code":"401013","message":"Oauth token is not valid"}

This means that whatever issue you are facing, it is related to your environment or to a bug in a specific (old) Node.js version.

Try reinstalling Node.js after clearing all your system cache, temporary files and Node.js-related configuration files.

Daniele Molinari
  • 541
  • 6
  • 29
  • Whoops I meant to use like example.com. Yeah that endpoint is fake but the service is trying to validate a token no one is gonna have. The fact you saw `this timed out` means it worked for you. I will try re-install. – Dave Stein Mar 12 '20 at 17:06
  • Yeahhhhh updated to 12 and it's fine. I was on 8 somehow. Thanks for pointing out the obvious thing to check sooner. 50 points to you sir :) – Dave Stein Mar 12 '20 at 17:08