What I want to achieve is when an express handler fails either by throwing an unhandled exception or returning an empty response like undefined or [], I want the handler to return a predefined mock response rather than failing. This means my server never fails as it either returns the normal real data or predefined mock data.
Of course I will only turn this on in development environment and never in production.
I think a middleware is ideal because I don't want to pollute every handler logic by injecting the response check.
Is this possible with a middleware in express? If not, what's a cleaner way of achieving this?
The return value of a middleware handler is irrelevant, because a middleware handler is asynchronous by nature. It does one of three things:
res.end(...) or similar.next(err).next().Errors can be caught with an additional error-handling middleware, and exceptions can be converted into errors as discussed in [ExpressJs]: Custom Error handler do not catch exceptions.
However, you cannot change a response after it has been sent. Moreover, you write
an express handler fails ... by ... returning an empty response
but an empty response is not a failure. If you want to treat empty responses as failures, but only in production, I suggest that you handle them as special errors. Instead of responding with res.json([]), say, you write next({emptyResponse: []}) and have special error-handling middleware in development only to handle these:
app.use(function(err, req, res, next) {
if (err.emptyResponse) {
console.error(err.emptyResponse);
res.end("Mock response");
} else next(err); // delegate to the standard error handler
});
Perhaps there is a misconception what a response is. The server streams the response to the client, only the client can "get" the response in this sense. Responses cannot be passed between middlewares.