Обработка ошибок в промисах в JavaScript

В этом руководстве вы узнаете, как работать с обработкой ошибок в промисах в JavaScript.

Предположим, у вас есть функция с именем getUserById(), которая возвращает промис:

function getUserById(id) {
    return new Promise((resolve, reject) => {
        resolve({
            id: id,
            username: 'admin'
        });
    });
}

Обычная ошибка

  • Во-первых, измените getUserById(), чтобы она выдавала ошибку вне промиса:
function getUserById(id) {
    if (typeof id !== 'number' || id <= 0) {
        throw new Error('Invalid id argument');
    }

    return new Promise((resolve, reject) => {
        resolve({
            id: id,
            username: 'admin'
        });
    });
}
  • Во-вторых, обработайте обещание, используя оба метода then() и catch() :
getUserById('a')
    .then(user => console.log(user.username))
    .catch(err => console.log(err));

Код выдает ошибку:

Uncaught Error: Invalid id argument

Когда вы создаете исключение вне промиса, вы должны поймать его с помощью try/catch :

try {
    getUserById('a')
        .then(user => console.log(user.username))
        .catch(err => console.log(`Caught by .catch ${error}`));
} catch (error) {
    console.log(`Caught by try/catch ${error}`);
}

Выход:

Caught by try/catch Error: Invalid id argument

Ошибки внутри промисов

Мы меняем getUserById(), чтобы она выдавала ошибку внутри промиса:

let authorized = false;

function getUserById(id) {
    return new Promise((resolve, reject) => {
        if (!authorized) {
            throw new Error('Unauthorized access to the user data');
        }

        resolve({
            id: id,
            username: 'admin'
        });
    });
}

И обработаем промис:

try {
    getUserById(10)
        .then(user => console.log(user.username))
        .catch(err => console.log(`Caught by .catch ${error}`));
} catch (error) {
    console.log(`Caught by try/catch ${error}`);
}

Выход:

Caught by .catch Error: Unauthorized access to the user data

Если вы сгенерируете ошибку внутри промиса, ее поймает метод catch(), а не try/catch.

Если вы связываете промисы, метод catch() будет ловить ошибки, возникающие в любом промисе. Например:

promise1 .then(promise2) .then(promise3) .then(promise4) .catch(err => console.log(err));

В этом примере, если в промисе1, промисе2 или промисе4 есть какая-либо ошибка, метод catch() обработает ее.

Вызов функции reject()

Генерация ошибки имеет тот же эффект, что и вызов reject(), как показано в следующем примере:

let authorized = false;

function getUserById(id) {
    return new Promise((resolve, reject) => {
        if (!authorized) {
            reject('Unauthorized access to the user data');
        }

        resolve({
            id: id,
            username: 'admin'
        });
    });
}

try {
    getUserById(10)
        .then(user => console.log(user.username))
        .catch(err => console.log(`Caught by .catch ${err}`));
} catch (error) {
    console.log(`Caught by try/catch ${error}`);
}

В этом примере вместо того, чтобы генерировать ошибку внутри промиса, мы явно вызвали reject(). В этом случае метод catch() также обрабатывает ошибку.

Отсутствующий метод catch()

В следующем примере не используется метод catch() для обработки ошибки внутри обещания. Это вызовет ошибку времени выполнения и завершит программу:

function getUserById(id) {
    return new Promise((resolve, reject) => {
        if (!authorized) {
            reject('Unauthorized access to the user data');
        }
        resolve({
            id: id,
            username: 'admin'
        });
    });
}

try {
    getUserById(10)
        .then(user => console.log(user.username));
    // the following code will not execute
    console.log('next');

} catch (error) {
    console.log(`Caught by try/catch ${error}`);
}

Выход:

Uncaught(in promise) Unauthorized access to the user data

Если обещание разрешено, вы можете опустить метод catch(). В будущем потенциальная ошибка может привести к неожиданной остановке программы.

Заключение

  • Внутри промиса метод catch() перехватит ошибку, вызванную оператором throw и reject().
  • Если возникает ошибка, а у вас нет метода catch(), механизм JavaScript выдает ошибку времени выполнения и останавливает программу.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript