javascripttypescriptasynchronouses6-promiseecmascript-2017

How to reject in async/await syntax?


How can I reject a promise that returned by an async/await function?

e.g. Originally:

foo(id: string): Promise<A> {
  return new Promise((resolve, reject) => {
    someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
  });
}

Translate into async/await:

async foo(id: string): Promise<A> {
  try{
    await someAsyncPromise();
    return 200;
  } catch(error) {//here goes if someAsyncPromise() rejected}
    return 400; //this will result in a resolved promise.
  });
}

So, how could I properly reject this promise in this case?


Solution

  • Your best bet is to throw an Error wrapping the value, which results in a rejected promise with an Error wrapping the value:

    } catch (error) {
        throw new Error(400);
    }
    

    You can also just throw the value, but then there's no stack trace information:

    } catch (error) {
        throw 400;
    }
    

    Alternately, return a rejected promise with an Error wrapping the value, but it's not idiomatic:

    } catch (error) {
        return Promise.reject(new Error(400));
    }
    

    (Or just return Promise.reject(400);, but again, then there's no context information.)

    In your case, as you're using TypeScript and foo's return value is Promise<A>, you'd use this:

    return Promise.reject<A>(400 /*or Error*/ );
    

    In an async/await situation, that last is probably a bit of a semantic mis-match, but it does work.

    If you throw an Error, that plays well with anything consuming your foo's result with await syntax:

    try {
        await foo();
    } catch (error) {
        // Here, `error` would be an `Error` (with stack trace, etc.).
        // Whereas if you used `throw 400`, it would just be `400`.
    }