3

I'm using Q for promises, but when setting up some tests I discover I see way in catching async errors thrown inside a function that returns a promise.

I tried to wrap it inside a Q.when and chained a fail and or as below a Q.fcall and a chained fail,but I can't get it to work.

    var func = function(){

               var deferred = Q.defer(); 
               setTimeout(function(){
                    throw new Error("async error");
               },100);

               return deferred.promise;

            }

            Q.fcall(func)
            .then(function(){
                console.log("success"); 
            })
            .fail(function(err){
                console.log(err); 
            })

Is there a way to to this?

Geert-Jan
  • 18,623
  • 16
  • 75
  • 137
  • See also [Asynchronous exception handling with bluebird promises](http://stackoverflow.com/q/25143476/1048572) – Bergi Jul 15 '15 at 20:51

1 Answers1

2

The exception in the setTimeout is not related anyhow to the promises, you have to catch that yourself using a try-catch-block.

Or you use Q.delay:

function func(){
    return Q.delay(100).then(function(){
        throw new Error("async error");
    });
}

func()
.then(console.log.bind(console, "success"))
.fail(console.log.bind(console));
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I realize that. The problem is, these functions executed through Q, may be developed outside of my control so I can't depend on proper try/catch. I'm now thinking of opting for a adding a timer to the surrounding promise to at least be able to do a reject after timeout to do correct exception-handling in my framework. Hoped there was a cleaner way though. – Geert-Jan Mar 19 '13 at 18:20
  • 1
    There's `Q.timeout` for that. If those third-party functions throw errors into nowhere, you can't really help it (or try to build something with `window.onerror`) – Bergi Mar 19 '13 at 20:05
  • Geert-Jan you just need to use async functions that returns promises (dot). That's simple and acceptable rule. Trying to hack native functions just to have setTimeout returning promise, will bring you more trouble than would help. – Mariusz Nowak Mar 20 '13 at 07:55
  • @Bergi I have created gist with your proposed solution but when i run it, it always print "success" in the console log. https://gist.github.com/pulakb/e9be0e273e8f7c2d92b6 – Pulak Kanti Bhattacharyya Aug 18 '14 at 15:23
  • 1
    @PulakKantiBhattacharyya: You don't need to use `fcall` when the function returns a promise (and you *can't* use it when there is no callback). I've updated the code sample to show how it's supposed to be used. – Bergi Aug 18 '14 at 15:29