Как правильно обрабатывать ошибки в Express? - PullRequest
24 голосов
/ 10 октября 2011

Я начинаю работать с Express JS и столкнулся с проблемой.Кажется, я не могу найти правильный способ обработки ошибок.

Например, у меня есть API веб-сервисов, который обслуживает объект, называемый «событие».Я хотел бы вернуть простую строку «not find event», когда пользователь отправляет идентификатор события, который не найден.Вот как я сейчас структурирую свой код:

app.get('/event/:id', function(req, res, next) {
    if (req.params.id != 1) {
        next(new Error('cannot find event ' + req.params.id));
    }

    req.send('event found!');
});

Когда я отправляю id , отличный от 1, Node вылетает со следующим выводом:

http.js:527
   throw new Error("Can't set headers after they are sent.");
         ^
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/usr/local/kayak/node_modules/express/node_modules/connect/lib/patch.js:62:20)
    at /usr/local/kayak/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19
    at [object Object].<anonymous> (fs.js:107:5)
    at [object Object].emit (events.js:61:17)
    at afterRead (fs.js:878:12)
    at wrapper (fs.js:245:17)

Из того, что я могу сказать, используя node.js отладчик , выполнение блока кода продолжается после вызова next(), что означает, что req.send('event found!') пытается выполнить.Я не хочу, чтобы это произошло.

Единственный найденный мной обходной путь - просто выбросить new Error() вместо «следующего», но это приводит к появлению страницы ошибки Express HTML по умолчанию.генерируется.Я хотел бы немного больше контроля, чем это.

Я потратил время на чтение раздела обработки ошибок документации Express, но я не мог понять это.

Ответы [ 3 ]

35 голосов
/ 10 октября 2011

Вы хотите проверить Экспресс-обработка ошибок .Оттуда:

app.param('userId', function(req, res, next, id) {
    User.get(id, function(err, user) {
        if (err) return next(err);
        if (!user) return next(new Error('failed to find user'));
        req.user = user;
        next();
    });
});

Недостаток сладости: return next(...)

19 голосов
/ 11 октября 2011

Это потому, что вы делаете это неправильно: вы уже сгенерировали ошибку (которая будет обработана Express и вернет страницу с 500 ошибками для пользователя или что-то в этом роде), но вы также пытаетесь отправить свой собственный ответthe client: res.send ('событие найдено!');

Вам действительно следует ознакомиться с Экспресс-руководством по обработке ошибок здесь: http://expressjs.com/guide/error-handling.html

Что бы я сделал в вашем примере,:

function NotFound(msg){
  this.name = 'NotFound';
  Error.call(this, msg);
  Error.captureStackTrace(this, arguments.callee);
} 

app.get('/event/:id', function(req, res, next){
  if (req.params.id != 1) {
    throw new NotFound('Cannot find event ' + req.params.id);
  } else {
    res.send('event found!');
  }
});

app.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.ejs');
    } else {
        next(err);
    }
});
10 голосов
/ 11 октября 2011

У вас есть пара проблем в вашем коде:

  • При ответе клиенту необходимо использовать response object (res вместо req).

  • При отправке ошибки на next, вы должны вернуть , поэтомуостальные функции не запускаются.

Вот ваш код после исправления этих ошибок:

app.get('/event/:id', function(req, res, next) {
    if (req.params.id != 1) {
        return next(new Error('cannot find event ' + req.params.id));
    }

    res.send('event found!'); // use res.send (NOT req.send)
}); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...