Skip to content

timeout isn't working #48

@pflannery

Description

@pflannery

AFAIK calling request.setTimeout(ms) does not automatically abort or fail the request when the timeout is reached. Instead, it simply emits a 'timeout' event on the request object where we would need to abort the request manually.

There isn't any logic in node-request-light capturing the timeout event so it will never timeout..

Recreation script (where 'request-light' is present in the node_modules folder):

const { xhr } = require('request-light');

async function testTimeout() {
  const timeoutMs = 1000;

  // This URL will wait for 10 seconds before responding
  const url = 'https://httpbin.org/delay/10';

  console.log(`Starting request to ${url} with a ${timeoutMs}ms timeout...`);
  const start = Date.now();

  try {
    const response = await xhr({
      url,
      timeout: timeoutMs
    });
    console.log(`Request finished successfully after ${Date.now() - start}ms (Status: ${response.status})`);
  } catch (error) {
    const duration = Date.now() - start;
    console.log(`Request failed after ${duration}ms`);
    if (error.status === 408 || error.message?.includes('timeout') || duration < 2000) {
      console.log('SUCCESS: The timeout was respected.');
    } else {
      console.log('FAILURE: The timeout was NOT respected. It likely waited for the full response.');
    }
    console.log('Error details:', error);
  }
}

testTimeout();

working nodejs example

const https = require('https');

function testWorkingTimeout() {
  const timeoutMs = 1000;
  const url = 'https://httpbin.org/delay/10';

  console.log(`Starting Node.js native request to ${url} with a ${timeoutMs}ms timeout...`);
  const start = Date.now();

  const req = https.get(url, (res) => {
    console.log('This should not be reached if timeout works.');
  });

  // Set the timeout
  req.setTimeout(timeoutMs);

  // Listen for the 'timeout' event (This is what request-light is missing)
  req.on('timeout', () => {
    console.log(`[TIMEOUT EVENT] Triggered after ${Date.now() - start}ms. Manually destroying the request...`);
    req.destroy(new Error('ETIMEDOUT')); 
  });

  req.on('error', (err) => {
    console.log(`[ERROR EVENT] Request failed as expected: ${err.message}`);
    console.log(`Total duration: ${Date.now() - start}ms`);
    
    if (Date.now() - start < 2000) {
        console.log('SUCCESS: The timeout was respected because we handled the event.');
    }
  });
}

testWorkingTimeout();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions