# 05. Error Handling

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

* `try-catch`,
* Использовать инструментарий Promise (`p.then()`, `p.catch()`, `Promise.try()`),
* Использовать утилиты, что бы в результате `await` вызова возвращать `[data, err]`.

## `try-catch`

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

```javascript
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`:

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

    return res;
}
```

## Structured return value

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

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

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

```javascript
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);
}
```

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

```javascript
const catchify = require("catchify");

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

* [`await-to-js`](https://github.com/scopsy/await-to-js)
* [`catchify`](https://github.com/majgis/catchify)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://strctr.gitbook.io/programming/01-languages/javascript/01-language/e-controls/e5-async/05-error-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
