05. Error Handling

Существует несколько подходов к обработкам ошибок внутри асинхронных функций:

  • try-catch,

  • Использовать инструментарий Promise (p.then(), p.catch(), Promise.try()),

  • Использовать утилиты, что бы в результате await вызова возвращать [data, err].

try-catch

Каждый вызов await, который может выбрасывать исключение необходимо оборачивать в catch:

async function asyncFunc() {
  try {
    await otherAsyncFunc();
  } catch (err) {
    console.error(err);
  }
}

// Equivalent to:
function asyncFunc() {
  return otherAsyncFunc().catch(err => {
    console.error(err);
  });
}

Error handling with Promises

При вызове await P можно навешивать различные обработчики на P и тем самым использовать семантику then() и catch() вместе с await:

async function Exec() {
    const res = await delay(2000)
        .then(() => 'resolved in 2000ms');
        .catch(() => 'error');

    return res;
}

Structured return value

Можно перенять подход свойственный go где в результате вызова операции возвращается data, err написав функцию:

// to.js
export default function to(promise) {
   return promise.then(
       data => [null, data]),
       err => [err, null]
   );
}

Тогда обработка асинхронного кода будет иметь вид:

import to from "./to.js";

async function asyncTask(cb) {
  let err, user, savedTask;

  [err, user] = await to(UserModel.findById(1));
  if (!user) return cb("No user found");

  [err, savedTask] = await to(
    TaskModel({ userId: user.id, name: "Demo Task" })
  );
  if (err) return cb("Error occurred while saving task");

  if (user.notificationsEnabled) {
    const [err] = await to(
      NotificationService.sendNotification(user.id, "Task Created")
    );
    if (err) return cb("Error while sending notification");
  }

  cb(null, savedTask);
}

У этого подхода есть преимущество в том, что на деструкции можно использовать значения по умолчанию:

const catchify = require("catchify");

async function example(promise) {
  const [error, value = { message: "Hello" }] = await catchify(promise);
  if (error) console.log(error);
  return value;
}

Last updated