2016-06-10 9 views
2

У меня есть маршрут, который сначала нужно запросить базу данных, затем с результатами запросить другую веб-службу, а затем с этим результатом отобразить страницу. У меня есть этот поток, и я пытаюсь разобраться в обработке ошибок. Учитывая, что я говорю с несколькими службами, я пытаюсь массировать ошибку, прежде чем возвращать их, чтобы выразить.expressJS обещание и обработка ошибок

Здесь структура кода маршрута:

Models.Episode.findById(request.params.episodeID) 
    .catch(function (error) { 
     throw (throwjs.notFound()); 
    }) 
    .then(function (episode) { 
     if (episode.getUser().id !== request.user.href) { 
      return next(throwjs.unauthorized("You do not have access to this podcast")); 
     } 
     return doSomeOtherAsyncStuff(); 
    }) 
    .then(function (queryResponse) { 
     renderPage(); 
    }) 
    .catch(function (error) { 
     next(error); 
    }); 

Моя проблема с первым уловом. Моя цель в этом улове состоит в том, чтобы переупаковать ошибку и остановить выполнение и отправить ошибку, чтобы выразить промежуточное ПО.

С тем, как написано выше, выполнение останавливается, но мой экспресс-обработчик ошибок не вызывается.

Я пытался переписывать первый улов, как

.catch(function(error){ 
    return next(error); 
}) 

Но это не решает проблему. Единственное решение, которое я нашел, - это переместить уловку до конца. Но тогда я теряю контекст места сбоя.

Любая подсказка относительно того, что я делаю неправильно? Спасибо, Olivier

+0

Вы действительно переписали первый улов, как в своем примере? потому что есть опечатка. – Seth

+0

@Seth Хорошая точка, я повторил, чтобы убедиться, что с опечаткой исправлено и получила ту же проблему. – otusweb

+0

@ t.niese, имея уловку в начале потока, я знаю, что единственное, что не удалось, - это утверждение выше. Если я добавлю улов только внизу, то я не уверен, что случилось – otusweb

ответ

2

Я бы рекомендовал использовать другой подход, чтобы вам не приходилось полагаться на долговременные цепочки обещаний. Используя следующий подход, вы отделили свою авторизацию и проверку, чтобы разделить промежуточное программное обеспечение, поскольку они не обязательно относятся к самому фактическому обработчику эпизодов. Плюс этот подход более идиоматично выражать.

Дополнительный бонус заключается в том, что вы можете передавать ошибки до обработчика ошибок, чтобы впоследствии отделить свои ошибки от ваших обработчиков маршрутов.

function validateEpisode(req, res, next) { 
    Models.Episode 
    .findById(req.params.episodeID) 
    .then(function(episode) { 
     req.yourApp.episode = episode; 
     next() // everything's good 
    }) 
    .catch(function(error) { 
     // would be better to pass error in next 
     // so you can have a general error handler 
     // do something with the actual error 
     next(throwjs.notFound()); 
    }); 
} 

function authUserByEpisode(req, res, next) { 
    if (req.yourApp.episode.getUser().id !== req.user.href) { 
    next(throwjs.unauthorized("You do not have access to this podcast")); 
    } 

    next(); // authorized 
} 

function episodeController(req, res) { 
    // do something with req.yourApp.episode 
} 

app.get('/episode/:id', validateEpisode, authUserByEpisode, episodeController) 
+0

Интересно. Мне придется поэкспериментировать с этим. Я все еще довольно новичок в этой вещи. Благодаря! – otusweb

0

Ну в конце концов, это связано со структурой throwjs я использую и то, что я использую неправильно

throw (throwjs.notFound()); 

должен быть

throw (new throwjs.notFound()); 

..