Is there a way to add middleware to the end of an express app
or router
chain that gets called to track whether or not the res
/ response was sent or not?
I mean, regardless of if:
For instance, if I wanted to log everything...
whether a response was successful or not, ie: it served a file via a express.static( ... )
middleware, some data fetched from a DB, or a custom middleware, or again... if it failed / threw an error...,
is there a way to invoke a callback at the very end?
So far from what I can understand, it seems like, by design, if a static file gets served successfully (via express.static), it doesn't call next()
, so the chain stops there.
And for any custom-made middlewares using res.send()
, you normally wouldn't want to call next()
afterwards since it could cause some undesirable side-effects (errors with headers getting resent).
For error-handlers, that's easier since all unsuccessful responses can be caught here.
But how can it output both successful / unsuccessful responses? Could this be something that should be done without middlewares?
The solution I went with ended up being slightly different from this one by @idbehold, but in a nutshell, at the very top of the express app middleware chain, I had to hook a callback to the res
Response object's finish
event which gets triggered for most (all?) HTTP status-codes I needed to track a successfully served request.
app.use( ( req, res, next ) => {
res.on( 'finish', () => {
var codeStr = String( res.statusCode );
codeStr = codeStr[res.statusCode < 400 ? 'green' : 'red'];
var output = [req.method.green, req.fullUrl().green, codeStr];
trace( output.join( ' ' ) );
} );
next();
});
I can now get things like:
Alright! So provided you also have an error-handler at the "end" of your middleware chain that serves something with an error 404
code, that will trigger the finish
event on the res
object.
Example of such an error-handler:
app.use( ( err, req, res, next ) => {
trace( "Error!".red );
trace( err );
res.status( 404 ).send(); // Triggers 'finish' on res.
})