Непрозрачное промежуточное программное обеспечение Express 3

Я пытаюсь настроить обработку ошибок для своего экспресс-приложения и работать с следующей проблемой.

Я определил промежуточное ПО ошибки и добавлю его как последнее промежуточное ПО:

// error handler
app.use(function(err, req, res, next) {

    console.log('JUST TESTING. ERROR HANLDER HAS BEEN CALLED...');
    next(err);
});

Теперь я ожидал бы, что это промежуточное ПО будет вызываться всякий раз, когда возникает ошибка:

app.get('/datenschutz', function(req, res, next){
        return next(new Error('Just testing')); // handle everything here
    });

Однако мое промежуточное программное обеспечение никогда не называется! Однако браузер отображает трассировку стека. Кажется, что есть другое промежуточное ПО, которое улавливает эту ошибку и обрабатывает ее, прежде чем я смогу что-нибудь сделать.

Проблема в том, что я не знаю, где это промежуточное ПО может быть определено, поскольку у меня очень простая настройка:

// setup ssl for local testing
var
    app = express();

app.
    use(express.static(__dirname + '/public')).
    use(express.bodyParser()).
    use(express.cookieParser());

Почему моя промежуточная программа обработки ошибок не вызывается? Где происходит эта обработка ошибок по умолчанию?

Спасибо!

* РЕДАКТИРОВАТЬ * Я вижу, что промежуточное ПО действительно работает. Однако это так, если я называю это из другой функции промежуточного программного обеспечения. Однако он не вызывается, если ошибка возникает внутри функции, определенной как экспресс-маршрут (GET, POST и т.д.). Это очень странно. Если я добавлю свое промежуточное ПО ошибки в обратные вызовы маршрута, он будет работать:

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();
    });

* РЕДАКТИРОВАТЬ 2 - НАЙДЕННЫЙ ПРИНЯТЫЙ ВАРИАНТ ОСНОВАНИЯ ** Я удивлен, что это нужно сделать так. Поскольку я прочитал много записей/вопросов об обработке ошибок в экспресс и никогда не упоминал эту возможность. Однако кажется, что если ошибка возникает внутри маршрутного обратного вызова, обычные обработчики промежуточного программного обеспечения ошибки не подберут его. Вам нужно будет определить обработчик ошибок на уровне маршрута.

app.all('*', function(err,req,res,next) {
        console.log('This is a global error handler at route level....');
        return next(err);
    });

Ответ 1

У меня тоже была эта проблема, но я не мог понять, почему она не работает, хотя я установил обработчик ошибок после app.user(app.router). Как оказалось, у меня уже был обработчик ошибок, о котором я не знал.

В частности, если вы используете экспресс-cli для создания приложения, как я, он автоматически добавит его в:

if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

К сожалению, для меня я добавил немного дополнительного ПО для своего приложения, что, следовательно, заслоняло этот оператор и, таким образом, помешало мне вызвать обработчик пользовательских ошибок.

Просто удалите это, а затем он должен работать правильно.

На стороне примечания, я должен упомянуть, что исходное решение все еще работало - даже с 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);
});

Ответ 2

Работает EDIT 2 (sabtioagoIT). Но только для тех, кто его пропустил, также работает решение emostar. Я понял, что нужно переместить вызов обработки ошибок "использовать" до конца, но, похоже, более простой вариант, предложенный emoster, использует app.router(до того, как обращение к ошибке "используйте" ).

Ответ 3

Обновлен ответ для пользователей Express 4 из документов Express 4. См. Пример из документов ниже. Обратите внимание, что app.router устарел и больше не используется. Я также добавил фиктивный маршрут, чтобы сделать порядок четким:

"Вы определяете промежуточное ПО обработки ошибок последним, после других приложений app.use() и маршрутов, например:

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
});

"