Propagating exceptions when using generators and promises

Viewed 168

This question is about emulating the behavior of async/await by using generators and promises, as described here:
https://gist.github.com/ChrisChares/1ed079b9a6c9877ba4b43424139b166d

Here is the minimal example exposing the problem:
The function async is taken verbatim from the link above.

function async(gen, context = undefined) {
 const generator = typeof gen === 'function' ? gen() : gen; // Create generator if necessary
 const { value: promise } = generator.next(context); // Pass last result, get next Promise
 if ( typeof promise !== 'undefined' ) {
  promise.then(resolved => async(generator, resolved))
  .catch(error => generator.throw(error)); // Defer to generator error handling
 }
}

function timesTwoPlusOne(num){ //multiplies argument by 2 and adds one, asynchronously
 return new Promise(function(resolve, reject) {
  async(function*(){
   //throw 'Fake exception 1' ;
   num = yield Promise.resolve( 2*num ) ; //multiply by 2, asynchronously
   //throw 'Fake exception 2' ;
   resolve( num + 1 ) ; //add one, synchronously
  }) ;
 });
}

//run an asynchronous procedure
async(function*(){
 let result ;
 try{
  result = yield timesTwoPlusOne(10) ;
 }catch(e){
  //the intention is to catch any exception happening inside `timesTwoPlusOne`
  console.log('CATCHED:', e) ;
 }
 console.log( result ) ;
}) ;

The code as it is, works fine. It prints 21 as expected.
However, inside the function timesTwoPlusOne there are two lines commented out.

When we uncomment the first one (throw 'Fake exception 1') and try again, that exception propagates up and is caught by the only catch block in the whole code.

That's exactly what I want. So far, so good.

But now, if we uncomment the second line (throw 'Fake exception 2') and leave the first one commented out, that exception IS NOT caught.

Why is the try/catch block able to catch the first exception, but not the second one?

0 Answers
Related