Execute Program

JavaScript Concurrency: Rejecting Promises

Welcome to the Rejecting Promises lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • So far, all of our promises have succeeded. But things fail all the time in real systems. Fortunately, promises have an error handling mechanism called "rejection".

  • To create a rejected promise, we can call Promise.reject(someReason). The "reason" argument tells us why the promise was rejected. Most reasons are Error objects, but other JavaScript values are allowed as well.

  • Just like with fulfilled promises, Execute Program represents rejected promises as objects. Instead of {fulfilled: someValue}, we get {rejected: someReason}.

  • >
    Promise.reject('user does not exist');
    Asynchronous Icon Async Result:
  • >
    Promise.reject(['an', 'array']);
    Asynchronous Icon Async Result:
    {rejected: ['an', 'array']}Pass Icon
  • The next example rejects with an Error, which Execute Program represents as a string.

  • >
    Promise.reject(new Error('oh no'));
    Asynchronous Icon Async Result:
  • We turn the error into a string because JavaScript has no way to represent literal error objects, just as it has no way to represent literal promises. Fortunately, this is more straightforward with errors: the string Error: oh no is what we get by calling .toString() on the error.

  • >
    new Error('user does not exist').toString();
    Result:
  • >
    Promise.reject(new Error('user does not exist'));
    Asynchronous Icon Async Result:
    {rejected: 'Error: user does not exist'}Pass Icon
  • Here's a code problem:

    This promise fulfills with what looks like an error message, "user does not exist". Change it to reject with an Error containing that message.

    const users = [
    {id: 1, name: 'Amir'}
    ];
    function findUser(id) {
    const user = users.find(u => u.id === id);
    if (user === undefined) {
    return Promise.reject(new Error('user does not exist'));
    } else {
    return user;
    }
    }
    findUser(2);
    Asynchronous Icon Async Result:
    Goal:
    {rejected: 'Error: user does not exist'}
    Yours:
    {rejected: 'Error: user does not exist'}Pass Icon
  • If we throw an exception inside a then callback, the exception is automatically converted into a promise rejection. The thrown error becomes the rejection reason.

  • The next example fails in the same way as the example above, but does it by throwing the error from a then.

  • >
    Promise.resolve()
    .then(() => {
    throw new Error('user does not exist');
    });
    Asynchronous Icon Async Result:
    {rejected: 'Error: user does not exist'}Pass Icon
  • Any then callbacks chained on the rejected promise will also reject with the same reason. Those then callbacks are never called.

  • This mirrors how exceptions work in regular JavaScript code. When a line of code throws an exception, the following lines don't execute.

  • >
    Promise.resolve()
    .then(() => {
    throw new Error('oh no');
    }).then(() => {
    return 5;
    });
    Asynchronous Icon Async Result:
    {rejected: 'Error: oh no'}Pass Icon