Почему node.js/bluebird потребляет исключение?

Глубоко в моем стеке обещаний я делаю этот вызов:

function isNameAvailable(name) {
    return registry.getName(name)
        .then(function(result) {
            return result ? false : true;
        });
}

К сожалению, и это ошибка программирования, реестр не определен. Мое приложение node.js не печатало никаких сообщений об ошибках. Есть идеи, почему? Я использую библиотеку обещаний bluebird.

Изменить

Вот код вызова. Я только что добавил улов, но он ничего не ловит.

function _checkAvailability(name) {
    return isNameAvailable(name)
        .then(function(isAvailabile) {
            if (isAvailabile) {
                return true;
            }
            else {
                throw new NameNotAvailable('Name "' + name + '" is not available');
            }
        })
        .catch(function(error) {
            console.log('isNameAvailable threw', error);
            throw error;
        })
}

В конечном итоге стек должен вернуться к функции, которая была вызвана express.js в результате HTTP-запроса. Это одно место, где я ловлю все ошибки и печатаю трассировку стека (но, очевидно, ничего не печатаю):

function createUser(req, res) {
    userService.createUser(req.body)
        .then(function(user) {
            res.status(201).send(user);
        })
        .catch(function(error) {
            log.trace(error);
            res.status(500).send({'message': error.toString()});
        });
}

person Naresh    schedule 07.11.2015    source источник
comment
Куда вы звонили isNameAvailable? Выкинуло точно.   -  person Bergi    schedule 07.11.2015
comment
Можете ли вы поделиться своим кодом? Из этого я бы предположил, что проблема в том, что вы не улавливаете ошибку.   -  person Isaac Madwed    schedule 07.11.2015
comment
Пожалуйста, смотрите мое редактирование для вызывающего абонента этого кода.   -  person Naresh    schedule 07.11.2015
comment
isNameAvailable делает синхронно throw исключение. Это не будет перехвачено никаким обработчиком .catch() возвращаемого значения, поскольку вы не возвращаете отклоненное обещание — метод catch никогда не выполняется. Ошибка будет обнаружена и преобразована в отклонение, если вы делаете что-то вроде somePromise.then(isNameAvailable) (или .then(_checkAvailability) в этом отношении)   -  person Bergi    schedule 07.11.2015
comment
Хорошо, это имеет смысл. Итак, основная проблема заключается в том, что isNameAvailable не возвращает промис из-за ошибки программирования, поэтому мы не можем ожидать, что then и catch сработают. Похоже, мне вообще не следует менять код, а просто убедиться, что я могу отлаживать такие проблемы.   -  person Naresh    schedule 07.11.2015
comment
Если вы хотите перехватить синхронное исключение, сгенерированное isNameAvailable(), вам либо нужна попытка/поймать внутри isNameAvailable(), либо вызывающему isNameAvailable() нужна попытка/поймать. Bluebird будет перехватывать исключения для вас только тогда, когда вы находитесь в обработчике .then(). Но вы выдаете исключение ДО того, как доберетесь до обработчика .then(). Итак, это просто обычное синхронное исключение. Он будет обработан только в том случае, если у вас есть код для его обработки.   -  person jfriend00    schedule 07.11.2015
comment
Спасибо вам всем. Если кто-то может написать краткое резюме, я отмечу его как правильный ответ.   -  person Naresh    schedule 07.11.2015


Ответы (1)


Отредактировано с учетом вашего обновления:

Нареш прав, вам нужно вернуть отклоненное обещание из доступного имени, если оно выдает. Вы могли бы попробовать

  function isNameAvailable(name) {
    try {
      return registry.getName(name)
        .then(function(result) {
          return result ? false : true;
        });
    } catch(e){
      return Promise.reject(e)
    }
  }

См. этот пост, чтобы узнать об ошибках, поглощаемых глубокими обещаниями.

http://www.mattgreer.org/articles/promises-in-wicked-detail/#promises-can-swallow-errors-

person Isaac Madwed    schedule 07.11.2015