2

Deep within my promise stack, I make this call:

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

Unfortunately, and this is a programming error, registry was undefined. My node.js application did not print any error message. Any ideas why? I am using the bluebird promise library.

Edit

Here's the calling code. I just added the catch, but it's not catching anything.

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

The stack should eventually roll back to the function that was called by express.js as a result of an HTTP request. That's one place where I am catching all errors and printing a stack trace (but obviously it is not printing anything):

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()});
        });
}
Naresh
  • 23,937
  • 33
  • 132
  • 204
  • Where were you calling `isNameAvailable`? It did throw for sure. – Bergi Nov 07 '15 at 14:10
  • Can you share more of your code? From this I would guess that the problem is that you aren't catching the error. – Isaac Madwed Nov 07 '15 at 15:19
  • Please see my edit for the caller of this code. – Naresh Nov 07 '15 at 15:39
  • `isNameAvailable` does synchronously `throw` an exception. This won't be caught in any `.catch()` handler on the return value, as you're not returning a rejected promise - the `catch` method is never executed. The error would be caught and transformed into a rejection if you were doing something like `somePromise.then(isNameAvailable)` (or `.then(_checkAvailability)` for that matter) – Bergi Nov 07 '15 at 16:25
  • Ok, that makes sense. So the basic issue is that `isNameAvailable` is not returning a promise due to a *programming error*, so we cannot expect `then` and `catch` to work. It appears that I should not change the code at all, instead just make sure that I am able to debug such issues. – Naresh Nov 07 '15 at 16:35
  • If you want to catch a synchronous exception thrown by `isNameAvailable()`, then you either need a try/catch inside of `isNameAvailable()` or the caller of `isNameAvailable()` needs a try/catch. Bluebird will only catch exceptions for you once you're in a `.then()` handler. But you are throwing an exception BEFORE you get to a `.then()` handler. So, it's just a normal synchronous exception. It will only get handled if you have code to handle it. – jfriend00 Nov 07 '15 at 17:17
  • Thank you all. If someone can write up a quick summary, I will mark it as the correct answer. – Naresh Nov 07 '15 at 19:24

1 Answers1

0

Edited to reflect your update:

Naresh is right, you need to return a rejected promise from is name available if it throws. You could try

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

See this post for error swallowing in deep promises.

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

Isaac Madwed
  • 986
  • 9
  • 23