Express 3 error middleware not being called - node.js

I am trying to setup error handling for my express app and running into the following problem.
I defined an error middleware and add it as the last middleware:
// error handler
app.use(function(err, req, res, next) {
console.log('JUST TESTING. ERROR HANLDER HAS BEEN CALLED...');
next(err);
});
Now I would expect this middleware to be called whenever an error occurs:
app.get('/datenschutz', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
});
However my middleware is never called! The browser does display the stack trace however.
This seems that there is another middleware that is catching this error and processing it before I can do anything about it.
The problem is that I have no clue where this middleware could be defined, as I have a very simple setup:
// setup ssl for local testing
var
app = express();
app.
use(express.static(__dirname + '/public')).
use(express.bodyParser()).
use(express.cookieParser());
Why is my error handling middleware not being called?
Where is this 'default' error handling taking place?
Thanks!
* EDIT *
I see that the middleware is indeed working. However this is the case if I call it from another middleware function.
However it is not being invoked if the error occurs inside a function defined as an express route (GET, POST, etc..). This is very strange.
If I add my error middleware to the route callbacks it then works:
app.get('/testError', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
}, function(err,req,res,next) {
console.log('This error handler is called!!');
return next();
});
* EDIT 2 - FOUND ACCEPTABLE WORKAROUND **
I am surprised it has to be done this way. As I had read many entries/questions about error handling in express and never found this possibility mentioned.
However it seems that if an error ocurrs inside a route callback regular error middleware handlers will not pick it up. You will need to define an error handler at route level.
app.all('*', function(err,req,res,next) {
console.log('This is a global error handler at route level....');
return next(err);
});

I had this problem as well, but I couldn't figure out why it wasn't working even though I set my error handler after the app.user(app.router). As it turns out, I already had an error handler that I wasn't aware of.
Specifically, if you use the express cli to generate an app like I did, it will automatically add in this in:
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
Unfortunately for me, I added a bit more middleware to my app, which consequently obscured this statement and thus prevented my custom error handler from being called.
Simply remove that and then it should work properly.
On a side note, I should mention that the original solution still worked - even with the app.use(express.errorHandler()).
app.all('*', function(err,req,res,next) {
console.log('This is a global error handler at route level....');
return next(err);
});

Updated answer for Express 4 users from the Express 4 docs. See example from docs below. Note that app.router is deprecated and no longer used. I also added a dummy route to make the ordering clear:
"You define error-handling middleware last, after other app.use() and routes calls; For example:
var bodyParser = require('body-parser');
app.use(bodyParser());
app.get('/', function(req, res) {
res.send('hello world');
})
app.use(function(err, req, res, next) {
// logic
});
"

EDIT 2 (sabtioagoIT) works. But just for those who missed it, emostar's solution also works.
I understood to move the error handling 'use' call to the end, but there seems to be an easier option as emoster suggests, use app.router (before the error handling 'use' call).

instead of making
app.get('/datenschutz', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
});
you can install express-async-errors
and just make
app.get('/datenschutz', function(req, res){
throw new Error('Just testing');
});
it works as expected

Related

Express 4: Handle every and all errors

While coding my app, I sometimes had a little mishap when typing my URLs in the browser, and thus sometimes got the error message:
Cannot GET /some/route
Which was true, since the route may was not defined.
But since this app is planned to enter production, I kinda don't want to use this flat message as my "error page".
Looking into the Express 4 docs, they tell me to .use() a middleware with 4 arguments. I did that. But I'd still get this issue...
Turns out that this message comes from the finalhandler module and my bet is, that this middleware comes before my error-catching, 4-argument middleware.
Here is a basic express app that I threw together while trying to find a solution:
var app = require("express")();
app.use("/yo", function(req, res, next){
res.send("Yo!");
});
app.use(function(error, req, res, next){
res.send("An error: "+error);
console.log(error);
});
app.listen(10000);
Accessing /yo works. But, / or /derp yields the Cannot GET message instead of my little middleware.
So, how is this done correctly, now?
The error middleware is only for actual errors, such as a middleware or route handler throwing an exception or passing an error to next().
If you want to provide a route handler for requests that do not match any existing routes, then just add a middleware after all of your app's routes/middleware like:
var app = require("express")();
app.use("/yo", function(req, res, next){
res.send("Yo!");
});
app.use(function(req, res, next) {
res.send('Could not route your request!');
});
app.use(function(error, req, res, next){
res.send("An error: "+error);
console.log(error);
});
app.listen(10000);

How to exit from a stack of middleware in Express.js

I am working a REST web application backend and I got some problem when linking my middleware together.
For example, the stack of the middlewares that each request has to go through is like [before1, service, after1], and here's the code for the middleware "before1", this is just the code I used for testing:
'use strict';
var express = require('express');
var router = express.Router();
router.use(function(request, response, next){
console.log('This is middleware BEFORE1');
var success = true
if (!success){
// Go the logging middleware underneath
next();
}
else{
// Go to the 'service' middleware
next('route');
}
})
router.use(function(request, response, next){
console.log('This is middleware LOGGING');
response.sendStatus(400);
response.end();
})
module.exports = router;
The above code is simply saying if the 'before1' succeeds, it should go straight to call 'service' middleware, and otherwise go to the logging middleware underneath and end the request. But my problem is that I can't figure out a way that it could skip the logging middleware, I searched and found next('route') could help, but it didn't work here. What have I missed?
Thanks in advance!
EDIT:
Or more preferably, it's the best if I can issue an error in any of my middleware and handle all types of errors properly using a error handler middleware.
The skeleton of my top level code is the following:
// An array of middleware to be executed asynchronously
operations = [before1, service, before2];
async.series(operations, function(err) {
if(err) {
// one of the functions passed back an error so handle it here
console.log('Handling error!!!!');
res.end();
// return next(err);
}
console.log('middleware get executed');
// no errors so pass control back to express
next();
});
But I am not sure How should change my middlewares accordingly in order to do that.
next is a node-style callback, which means fn(err, ..), so your next('route') will only work to invoke errorhandlers.
You can implement your series directly by supplying an array of functions to the route, and using an express error handler as the catch all (see http://expressjs.com/guide/error-handling.html)

Kraken JS middleware and exceptions

I'm experimenting with KrakenJS, trying to build an basic API to understand things.
One thing I'm unsure of is the middleware, specifically the 404/500 error handling.
"fileNotFound": {
"enabled": true,
"priority": 130,
"module": {
"name":"path:./lib/exceptions/404"
}
}
This catches any 404 errros, and then I handle that myself in my own configuration. However, why is this fileNotFound thrown? Where is serverError thrown for 500 errors?
I would like to define my own files for other exceptions like a 403, however how would I get this to trigger a middleware?
As #HeadCode mentioned, definitely read up on meddleware to understand how middleware gets loaded a bit better.
That said, we have to go over a few things in order to make what's happening more clear.
Handling 404s
First, let's go over how one would typically register a 404 handler in a plain old express app.
Typically you'd have the final middleware in your middleware continuation chain just assume that, if we made it that far without bailing, we simply cannot find the resource. Here's an example:
var express = require('express');
var app = express();
app.get('/firstRoute', function handler(req, res) { res.send('found me'); });
app.get('/secondRoute', function handler(req, res) { res.send('found me'); });
app.use(function notFoundHandler(req, res, next) {
res.status(404).send('Route Not Found');
});
app.listen(8000, function onListen() { console.log('listening on 8000...'); });
Since routes are resolved in the order they're added in Express 4, as long as your 404 handler is last you can be certain no other route matched.
This pattern is briefly described in the Express FAQs.
Handling 500s
Now let's move on to 500s.
Express has the concept of an error-handling middleware (also described on the Express site). An error handling middleware requires an arity of 4 (i.e., takes four arguments) and that's the only difference. They're only executed if an error is signaled which is done by passing an object into your next call. Easier explained in code:
var express = require('express');
var app = express();
app.get('/firstRoute', function handler(req, res) { res.send('found me'); });
app.get('/secondRoute', function handler(req, res) { throw new Error('oops'); });
app.use(function notFoundHandler(req, res, next) {
res.status(404).send('Route Not Found');
});
app.use(function errorHandler(err, req, res, next) {
res.status(500).send('Broken. :(');
});
app.listen(8000, function onListen() { console.log('listening on 8000...'); });
In the above example, errorHandler will only execute if either 1) another middleware or route handler throws an error or 2) we call next with an argument*, .e.g. next(new Error('oops')).
Go ahead and run that. if you visit /notFound or any random route, you'll correctly get a 404. If you visit /firstRoute you'll get found me, and if you go to secondRoute you'll get Broken. :(.
What about kraken?
Kraken—or more accurately, meddleware—just moves defining your middleware into your config. That little block of json you copied above is basically functionally equivalent to the following in a vanilla express app:
var fileNotFound = require('./lib/exceptions/404');
// ... app.use() everything with a priority lower than 130 ...
app.use(fileNotFound());
// ... app.use() everything with a priority *greater* than 130 ...

How to manage HTTP errors in Node.js

Hi I'm developing my first Node.js application and I found my first issue in something really basic, I can't catch the HTTP errors (404, 500, ...)
I've followed the doc (I think so) but I suppose that I'm missing something.
This is my code:
var express = require('express')
app = express()
app.use(express.logger('dev'));
app.get('/', function(req, res) {
res.send('Hellow World!!!')
})
app.use(app.router);
app.use(function(err, req, res, next) {
console.error('Oh!! ERROR');
console.error('My ERROR: ' + JSON.stringify(err));
});
app.listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
Thanks in advance.
So the way express works is if it hits the end of the entire stack of middleware and route handlers and nothing has responded yet, it's going to send the fallback 404 response automatically without raising an error. This is why your error handling middleware isn't being called. By default, express doesn't consider a 404 an error, which is probably the right way to think of it.
If you want to customize this, you can put a middleware at the end of your stack to either serve a custom 404 page directly or call next with an error if you prefer that way.
app.get('/'...
app.get('/two'...
app.get(/'three'...
app.use(middleware1...
app.use(middleware2...
app.use(app.router);
app.use(function (req, res, next) {
//Option 1: respond here
return res.status(404).render('my_404_view');
//Option 2: trigger error handler
return next(new Error('404ed!'));
}
Option 2 will trigger your error handling middleware. There you will have to get info from the error object to determine the desired view to render and status code to send. I personally define an errors.NotFound class that has a 404 code and lets me render a friendly 404 page view.

Centralizing error handling in an express.js-based app

I just recently started working on an express.js based application, which also uses the pg module (https://github.com/brianc/node-postgres)
I also spent a significant amount of time, reading about node and express approach error handling, the benefits of properly designing middleware, etc. Yet, a recurring problem is still buzzing me without a solution.
Say, I have the following router method:
app.get("/:someThing/:someId", function(req, res, next) {
pgClient.query("some SQL query", function(err, data) {
if (err) { return next(err); } // some 500 handler will take it
if (data.rows.length == 0) {
next(); // send it over to a 404 handler
}
//finally, here we get the chance to do something with the data.
//and send it over via res.json or something else
});
});
If I've read correctly, this should be the proper way to do it. Yet, I bet you can also admt that it is too much of boilerplate to rewrite over and over ... and over again, even in the very same router method, in case we have multiple nested callbacks.
I've been asking myself what the best way to handle such a situation centrally would be. All of my ideas involve intercepting the pgClient.query method. In one, the query method will simply throw the error instead of passing it to the callback. In another, the call to the pgClient.query will send the router method's next to pgClient. Then the intercepted query method will know how to deal with the next being passed to it.
From what I know, throwing errors around is not really the appropriate way to get it to the 500 handlers. On another hand, passin next as an option to pgClient, gives such a low level a lot of knowledge about the the layers above, which based on my knowledge and experience, can lead to coupling, and is not very good either.
What do you suggest?
You can use connect-domain middleware. It works with connect and express and based on Doman API.
You need to add connect-domain middleware as first middleware in stack. Thats all. Now you can throw errors everywhere in your async code and they will be handled with domain middleware and passed to express error handler.
Simple example:
// Some async function that can throw error
var asyncFunction = function(callback) {
process.nextTick(function() {
if (Math.random() > 0.5) {
throw new Error('Some error');
}
callback();
});
};
var express = require('express');
var connectDomain = require('connect-domain');
var app = express();
app.use(connectDomain());
// We need to add router middleware before custom error handler
app.use(app.router);
// Common error handler (all errors will be passed here)
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
app.listen(3131);
// Simple route
app.get('/', function(req, res, next) {
asyncFunction(function() {
res.send(200, 'OK');
});
});

Resources