baryshev / connect-domain

MIT License
85 stars 11 forks source link

nested promises not working #7

Open vitalets opened 11 years ago

vitalets commented 11 years ago

cant get it working with nested promises: this works:

    Q.ninvoke(db, 'collection', 'users')
    .then(function(collection) {
       throw new Error('123');   // error in first level
      return Q.ninvoke(collection, 'findOne', {url: id})
       .then(function(item) {
        ...

but this don't:

    Q.ninvoke(db, 'collection', 'users')
    .then(function(collection) {
      return Q.ninvoke(collection, 'findOne', {url: id})
       .then(function(item) {
           throw new Error('123');  // error in nested promise
           ...

any help appreciated..

mbrubin56 commented 11 years ago

When you throw an exception inside a promise, you are causing the promise to resolve as a rejection. If you had a fail handler at the end of your chain, you would see the fail handler get called. Promises allow for fail handlers to be attached at any point (even after the promise has been resolved as a rejection or success), so even if you're missing a fail handler in this code, the promise will not leak the exception; it will consider the exception as causing the promise to resolve to a rejection, and will dutifully notify any fail handlers if they are attached in the future. If you want the exception to leak out of the promise wrappers, you need to call end(). If you do that, you will then allow the exception to break free, as it were, of the promise, and get caught by the domain error handler.

vitalets commented 11 years ago

thanks for explanation. so the correct code to catch error in nested pormise is:

Q.ninvoke(db, 'collection', 'users')
    .then(function(collection) {
      return Q.ninvoke(collection, 'findOne', {url: id})
       .then(function(item) {
         throw new Error('123');
       });
     })
     .end();

?

mbrubin56 commented 11 years ago

I haven't tested the code, but that should cause your exception to escape the promises and leak out. It should then be able to be caught by your domain's error handler.