Home > front end >  node.js express: Is there a way to cancel http response in middleware?
node.js express: Is there a way to cancel http response in middleware?

Time:04-20

I am writing a timeout middleware with express in node.js.

app.use((req, res, next) => {
  res.setTimeout(3000, () => {
    console.warn("Timeout - response end with 408")
    res.status(408).json({ "error": "timeout 408" });
    // !!! error will happen with next function when call like `res.send()`:
    // Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
  next()
})

If there's an endpoint that takes more than 3000 ms, my middleware will repsond with 408. However, the next function will respond again. I don't want to check if the response has been already sent by res.headersSent api every time.

Is there a better way to handle this - like the title said - to cancel the next response in the middleware?


CodePudding user response:

It's your own code in the response handler that is still running (probably waiting for some asynchronous operation to complete). There is no way to tell the interpreter to stop running that code from outside that code. Javascript does not have that feature unless you put that code in a WorkerThread or a separate process (in which case you could kill that thread/process).

If you're just trying to suppress that warning when the code eventually tries to send its response (after the timeout response has already been sent), you could do something like this:

app.use((req, res, next) => {
  res.setTimeout(3000, () => {
    console.warn("Timeout - response end with 408")
    res.status(408).json({ "error": "timeout 408" });

    // to avoid warnings after a timeout sent, 
    // replace the send functions with no-ops
    // for the rest of this particular response object's lifetime
    res.json = res.send = res.sendFile = res.jsonP = res.end = res.sendStatus = function() { 
        return this;
    }
  });
    
  next();
});
  • Related