51 lines
5.6 KiB
Markdown
51 lines
5.6 KiB
Markdown
---
|
||
sidebar_position: 3
|
||
---
|
||
|
||
# Обработка ошибок
|
||
- `.catch` перехватывает все виды ошибок в промисах: будь то вызов `reject()` или ошибка, брошенная в обработчике при помощи `throw`.
|
||
- `.then` также перехватывает ошибки таким же образом, если задан второй аргумент (который является обработчиком ошибок).
|
||
- Необходимо размещать `.catch` там, где мы хотим обработать ошибки и знаем, как это сделать. Обработчик может проанализировать ошибку (могут быть полезны пользовательские классы ошибок) и пробросить её, если ничего не знает о ней (возможно, это программная ошибка).
|
||
- Можно и совсем не использовать `.catch`, если нет нормального способа восстановиться после ошибки.
|
||
- В любом случае нам следует использовать обработчик события `u`nhandledrejection` (для браузеров и аналог для других окружений), чтобы отслеживать необработанные ошибки и информировать о них пользователя (и, возможно, наш сервер), благодаря чему наше приложение никогда не будет «просто умирать».
|
||
|
||
## Неявный try…catch
|
||
Вокруг функции промиса и обработчиков находится `«невидимый try..catch»`. Если происходит исключение, то оно перехватывается, и промис считается отклонённым с этой ошибкой.
|
||
|
||
«Невидимый try..catch» вокруг промиса автоматически перехватывает ошибку и превращает её в отклонённый промис.
|
||
|
||
Это работает не только в функции промиса, но и в обработчиках. Если мы бросим ошибку (throw) из обработчика (.then), то промис будет считаться отклонённым, и управление перейдёт к ближайшему обработчику ошибок.
|
||
|
||
## Пробрасывание ошибок
|
||
Мы можем иметь столько обработчиков `.then`, сколько мы хотим, и затем использовать один `.catch` в конце, чтобы перехватить ошибки из всех обработчиков.
|
||
|
||
В обычном `try..catch` мы можем проанализировать ошибку и повторно пробросить дальше, если не можем её обработать. То же самое возможно для промисов.
|
||
|
||
Если мы пробросим `(throw)` ошибку внутри блока `.catch`, то управление перейдёт к следующему ближайшему обработчику ошибок. А если мы обработаем ошибку и завершим работу обработчика нормально, то продолжит работу ближайший успешный обработчик `.then`.
|
||
|
||
## Необработанные ошибки
|
||
Что произойдёт, если ошибка не будет обработана? \
|
||
В случае ошибки выполнение должно перейти к ближайшему обработчику ошибок.
|
||
|
||
Что происходит, когда обычная ошибка не перехвачена try..catch? Скрипт умирает с сообщением в консоли. Похожее происходит и в случае необработанной ошибки промиса.
|
||
|
||
JavaScript-движок отслеживает такие ситуации и генерирует в этом случае глобальную ошибку. Вы можете увидеть её в консоли, если запустите пример выше.
|
||
|
||
В браузере мы можем поймать такие ошибки, используя событие unhandledrejection:
|
||
```js
|
||
window.addEventListener('unhandledrejection', function(event) {
|
||
// объект события имеет два специальных свойства:
|
||
alert(event.promise); // [object Promise] - промис, который сгенерировал ошибку
|
||
alert(event.reason); // Error: Ошибка! - объект ошибки, которая не была обработана
|
||
});
|
||
|
||
new Promise(function() {
|
||
throw new Error("Ошибка!");
|
||
}); // нет обработчика ошибок
|
||
```
|
||
|
||
Если происходит ошибка, и отсутствует её обработчик, то генерируется событие `unhandledrejection`, и соответствующий объект `event` содержит информацию об ошибке.
|
||
|
||
Обычно такие ошибки неустранимы, поэтому лучше всего – информировать пользователя о проблеме и, возможно, отправить информацию об ошибке на сервер.
|
||
|
||
🚀 **Источник: [https://learn.javascript.ru/promise-error-handling](https://learn.javascript.ru/promise-error-handling)** |