node-http-proxy icon indicating copy to clipboard operation
node-http-proxy copied to clipboard

feat: allow sending a custom proxy timeout error

Open rowanmanning opened this issue 2 years ago • 1 comments
trafficstars

When using proxyTimeout it's very difficult to tell the difference between a regular socket hangup and a timeout because, in both cases, an ECONNRESET error is thrown. Ideally we should be able to identify when a proxy request has failed because it took too long, this would allow us to do things like send appropriate 504 status code.

Suddenly throwing a different error would probably be considered a breaking change because it's possible that users of http-proxy are relying on the ECONNRESET error. I decided to add the custom timeout error behind a new option for now so that people can opt into using it.

If you set this option:

var proxy = httpProxy.createProxyServer({
  target: 'http://example.com',
  proxyTimeout: 100,
  proxyTimeoutCustomError: true
});

Then the error that gets thrown will have a message of "The proxy request timed out" and a code of ETIMEDOUT to match Node.js: https://nodejs.org/api/errors.html#common-system-errors

This allows for custom error handling code like this:

proxy.on('error', function(err, req, res) {
  if (err.code === 'ETIMEDOUT') {
    res.writeHead(504);
  } else {
    res.writeHead(503);
  }
  // ...
});

A note on implementation

I had to switch from request.abort() to request.destroy() for this to work. request.abort() has been deprecated since Node.js v14.1.0 and request.destroy() has been available since Node.js v0.3.0 so I think this is a safe bet. If you're worried about it then I could always switch to request.abort() for the case when proxyTimeoutCustomError is falsy.


Resolves #1331.

rowanmanning avatar Oct 07 '23 12:10 rowanmanning