The official documentation of expressjs at https://expressjs.com/en/guide/error-handling.html states the following:
Notice that when not calling “next” in an error-handling function, you are responsible for writing (and ending) the response. Otherwise those requests will “hang” and will not be eligible for garbage collection.
Their example for the last custom handler is as follows:
...
app.use(logErrors)
app.use(clientErrorHandler)
app.use(errorHandler)
function errorHandler (err, req, res, next) {
res.status(500)
res.render('error', { error: err })
}
At this point I am not sure if this example actually ended the response. Is it already ended when the last custom error handler calls .status() and .render() ?
The documentation further states
res.end([data] [, encoding]) Ends the response process. This method actually comes from Node core, specifically the response.end() method of http.ServerResponse. Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().
This implies to me, that e.g. send() will end the response. In restify, which is built on express, the documentation states
Unlike other REST frameworks, calling res.send() does not trigger next() automatically. In many applications, work can continue to happen after res.send(), so flushing the response is not synonymous with completion of a request.
This is why unsure, whether just calling send(),json() or status is really enough to release those resources to garbage collection
I would have expected that we either have to
- call next() with no parameter that (so that the default handler will eventually end it) or
- res.end() to end manually
after we have written a response to the client by
- res.status() or
- res.status(...).res.send(...) or
- res.send(...) or
What is the proper way to end the response in a custom error handler?
CodePudding user response:
res.send
internally calls res.end
, but res.status
only sets the HTTP status and does not call res.end
. With res.render
, it depends on the callback function. The default callback uses res.send
to output the rendering (implying res.end
), or next(err)
in case of a rendering error.
So res.send
, res.end
and res.render
(with the default callback) will end the response.