Возвращает ошибки во вложенном then и обещает ExpressJS / NodeJS

#javascript #node.js #express #promise #sequelize.js

#javascript #node.js #выразить #обещание #sequelize.js

Вопрос:

У меня небольшая путаница при возврате ошибок из вызовов функций. Для примера я использую sequelizeJS, чтобы проиллюстрировать эту точку зрения. Обычно:

Первый.Ctrl

 var second_ctrl = require( '../ctrl/second');
testCode : function(req, res, next){
    return second_ctrl.getData()
          .then(function(resultData){
                res.json(resultData);
          })
          .catch(function(error){
                res.json(error)
          })
}
  

Второй.Ctrl

 getData : function(){
    return models.Data.findAll()              
}
  

Любая ошибка в getData findAll приведет к перехвату блока first_ctrl . Но если мне нужно выполнить некоторые манипуляции, такие как:

Второй.Ctrl — манипуляция

 getData : function(){
    return models.Data.findAll()
          .then(function(result){
                if(result == null)
                   throw new Error ('No data found');
                return  resu<
          })
          .catch(function(error){
                throw error;
                //return error
          })
}
  

Я пытался использовать throw error, return error и удаление внутреннего блока catch, но в обоих случаях выполнение переходит к блоку then в first_ctrl с resultData, получившим объект error .

Какова наилучшая практика для такого рода ситуаций, поскольку эти вложенные вызовы могут идти еще глубже (first_ctrl -> second_ctrl -> third_ctrl)

Дайте мне знать. С нетерпением жду ваших мыслей

Комментарии:

1. вы уверены, что попали в блок then при выбрасывании? Ожидаемое поведение похоже на ваш пример, и вы должны оказаться в своем внешнем блоке catch (вам даже не нужен внутренний блок catch, если вы хотите всегда перехватывать во внешнем блоке).

2. даже я пытался удалить внутренний блок catch, но я заканчиваю на блоке then first_ctrl.

3. @adeneo: насколько я знаю, для promises я должен использовать библиотеку promise, такую как q или bluebird. Разве это невозможно без них, как обычно. Если возможно, пожалуйста, дайте мне знать, как я могу с помощью фрагмента.

4. Я не думаю, что я это понял. Вы выдаете ошибку и попадаете в первый блок catch, но вы не попадаете во второй цепной блок catch, потому что цепочка восстанавливается. Насколько я могу судить, выбрасывание внутри блока catch должно работать.

5. jsfiddle.net/adeneo/byt9b6oz

Ответ №1:

Пока не полный ответ, но, надеюсь, он поможет вам попасть в нужное русло.

Ваша основная идея верна. Работает следующий код:

 const myPromise = Promise.reject(new Error('some error'))
  .then(res => console.log('inner then'))
  .catch(err => {
    console.log('inner err');
    throw err
  })
  .then(res => console.log('outer then'))
  .catch(err => console.log('outer err'));
// logs:
//   inner err
//   outer err
  

Итак, следующие вещи, которые я могу себе представить, являются возможной причиной нашей проблемы:

  • вы находитесь во внешнем блоке catch, не замечая этого (вы вызываете res.json() там, а также во внешнем then — как вы узнаете, какой из них вызывается)
  • вы используете библиотеку promise с ошибками.

Надеюсь, это поможет хотя бы немного.

Комментарии:

1. Я не использую какую-либо библиотеку promise и не создаю какой-либо объект promise в second_ctrl. Это так, как упоминалось выше. Я думаю, это причина? Я должен использовать библиотеку обещаний. Верно?

2. Что возвращает models.Data.findAll(), кроме обещания? Он обязательно возвращает что-то, что можно использовать, иначе ваш блок then также не будет вызван