You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
.catch(err=>alert(err)) // SyntaxError: Unexpected token < in JSON at position 0
26
26
```
27
27
28
-
Самый лёгкий путь, перехватить все ошибки - добавить `.catch` в конец цепочки:
28
+
Самый лёгкий путь перехватить все ошибки - это добавить `.catch` в конец цепочки:
29
29
30
30
```js run
31
31
fetch('/article/promise-chaining/user.json')
@@ -106,13 +106,13 @@ new Promise((resolve, reject) => {
106
106
107
107
## Повторное пробрасывание ошибок (rethrowing)
108
108
109
-
Как мы уже заметили, `.catch` ведёт себя как `try..catch`. У нас может быть столько обработчиков `.then`, сколько мы хотим, и затем использовать один `.catch`, в конце, чтобы перехватить ошибки из всех обработчиков.
109
+
Как мы уже заметили, `.catch` ведёт себя как `try..catch`. У нас может быть столько обработчиков `.then`, сколько мы хотим, и затем использовать один `.catch` в конце, чтобы перехватить ошибки из всех обработчиков.
110
110
111
111
В обычном `try..catch` мы можем проанализировать ошибку и повторно пробросить дальше, если не можем её обработать. То же самое возможно для промисов.
112
112
113
-
Если мы пробросим (`throw`) ошибку внутри блока `.catch`, то управление перейдет к следующему ближайшему обработчику ошибок. И если мы обработаем ошибку, и завершим работу обработчика нормально, то продолжит работу ближайший успешный обработчик `.then`.
113
+
Если мы пробросим (`throw`) ошибку внутри блока `.catch`, то управление перейдет к следующему ближайшему обработчику ошибок. И если мы обработаем ошибку и завершим работу обработчика нормально, то продолжит работу ближайший успешный обработчик `.then`.
114
114
115
-
В примере ниже,`.catch` успешно обрабатывает ошибку:
115
+
В примере ниже `.catch` успешно обрабатывает ошибку:
116
116
117
117
```js run
118
118
// the execution: catch -> then
@@ -159,7 +159,7 @@ new Promise((resolve, reject) => {
159
159
});
160
160
```
161
161
162
-
Затем управление переходит от первого блока `.catch``(*)`, к следующему `(**)`, вниз по цепочке.
162
+
Затем управление переходит от первого блока `.catch``(*)` к следующему `(**)`, вниз по цепочке.
163
163
164
164
В следующем разделе мы рассмотрим практическое применение повторного пробрасывания.
На данный момент код пытается загрузить ответ как JSON строку, несмотря ни на что и умирает с синтаксической ошибкой. Вы можете сами увидеть это, запустите представленный выше пример, так как файл `no-such-user.json` не существует.
184
+
На данный момент код пытается загрузить ответ как JSON строку, несмотря ни на что и умирает с синтаксической ошибкой. Вы можете сами увидеть это, запустив представленный выше пример, так как файл `no-such-user.json` не существует.
185
185
186
186
Это не хорошо, потому что ошибка просто проваливается сквозь всю цепочку, без подробностей: что за ошибка и где.
187
187
188
-
Итак, давайте добавим ещё один шаг: мы должны проверить свойство `response.status`, которое есть в HTTP и если статус не 200, тогда пробросим ошибку.
188
+
Итак, давайте добавим ещё один шаг: мы должны проверить свойство `response.status`, которое есть в HTTP, и если статус не 200, тогда пробросим ошибку.
.catch(alert); // HttpError: 404 for .../no-such-user.json
212
212
```
213
213
214
-
1. Мы создали специальный класс для HTTP ошибок, чтобы отличать их от других типов ошибок. Кроме того, новый класс имеет конструктор, который принимает объект `response` и сохраняет его ошибках. Таким образом, код обработки ошибок сможет получить к нему доступ.
215
-
2. Затем мы объединили код запроса данных и обработки ошибки в одну функцию, которая получает данные по `url`*и* обрабатывает ответ со статусом 200 как выполнившийся, а любой другой статус, как ошибку. Это удобно, потому что нам часто необходима такая логика.
214
+
1. Мы создали специальный класс для HTTP ошибок, чтобы отличать их от других типов ошибок. Кроме того, новый класс имеет конструктор, который принимает объект `response` и сохраняет его в ошибке. Таким образом, код обработки ошибок сможет получить к нему доступ.
215
+
2. Затем мы объединили код запроса данных и обработки ошибки в одну функцию, которая получает данные по `url`*и* обрабатывает ответ со статусом 200 как выполнившийся, а любой другой статус как ошибку. Это удобно, потому что нам часто необходима такая логика.
216
216
3. Сейчас `alert` показывает более полезное сообщение.
217
217
218
218
Самое замечательное в нашем собственном классе для ошибок заключается в том, что мы можем легко проверить его в коде обработки ошибок.
219
219
220
-
Например, мы можем создать запрос и после, если получим 404 -- попросить пользователя поправить введённую информацию.
220
+
Например, мы можем создать запрос и после, если получим 404, попросить пользователя поправить введённую информацию.
221
221
222
222
Код ниже загружает пользователя с указанным именем из github. Если такого пользователя не существует, то он запрашивает ввести правильное имя:
223
223
@@ -247,7 +247,7 @@ demoGithubUser();
247
247
248
248
Обратите внимание: в приведённом коде `.catch` перехватывает все ошибки, но "знает как обработать" только `HttpError 404`. В данном примере это означает, что пользователя не существует, в этом случае `.catch` повторно запускает ввод имени.
249
249
250
-
Для других ошибок, код понятия не имеет, что могло пойти не так. Может быть это программная ошибка или что-то другое. Поэтому просто повторно пробрасывает её в строке с `(*)`.
250
+
Для других ошибок код понятия не имеет, что могло пойти не так. Может быть это программная ошибка или что-то другое. Поэтому просто повторно пробрасывает её в строке с `(*)`.
251
251
252
252
## Необработанные ошибки
253
253
@@ -264,9 +264,9 @@ new Promise(function() {
264
264
}); // без .catch в самом конце!
265
265
```
266
266
267
-
В случае ошибки промис становится "отклонённым" и выполнение переходит к ближайшему обработчику ошибок. Но в примере ниже нет никакого обработчика. Поэтому ошибка как-бы "застревает".
267
+
В случае ошибки промис становится "отклонённым", и выполнение переходит к ближайшему обработчику ошибок. Но в примере ниже нет никакого обработчика. Поэтому ошибка какбы "застревает".
268
268
269
-
На практике, как и при обычных необработанных ошибках это означает, что что-то пошло не так, скрипт, возможно, умер.
269
+
На практике, как и при обычных необработанных ошибках, это означает, что что-то пошло не так, скрипт, возможно, умер.
270
270
271
271
Большинство JavaScript движков отслеживают такие ситуации и генерируют в этом случае глобальную ошибку. Мы можем увидеть это в консоли.
272
272
@@ -288,21 +288,21 @@ new Promise(function() {
288
288
289
289
Это событие является частью [HTML стандарта](https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections).
290
290
291
-
Если происходит ошибка и она не перехватывается, отсутствует `.catch`, тогда тригерится событие `unhandledrejection` и объект `event` получает информацию об ошибке, поэтому мы можем хоть как-то отреагировать на ошибку.
291
+
Если происходит ошибка и она не перехватывается, отсутствует `.catch`, тогда тригерится событие `unhandledrejection`, и объект `event` получает информацию об ошибке, поэтому мы можем хоть как-то отреагировать на ошибку.
292
292
293
-
Обычно такие ошибки неустранимы, поэтому лучше всего - информировать пользователя о проблеме и возможно, отправить информацию об ошибке на сервер.
293
+
Обычно такие ошибки неустранимы, поэтому лучше всего - информировать пользователя о проблеме и, возможно, отправить информацию об ошибке на сервер.
294
294
295
295
В не браузерных средах, таких как Node.JS, есть другие похожие способы отслеживания необработанных ошибок.
296
296
297
297
298
298
## Итого
299
299
300
-
-`.catch` перехватывает все виды отклонённых промисов: будет это вызов `reject()` или ошибка пробросится (throw) в обработчике.
300
+
-`.catch` перехватывает все виды отклонённых промисов: будь то вызов `reject()` или проброшенная в обработчике ошибка.
301
301
- Необходимо размещать `.catch` там, где мы точно хотим обработать ошибку и знаем, как её обработать. Обработчик должен проанализировать ошибку (помогают пользовательские классы ошибок) или повторно пробросить её, если ничего не знает о ней.
302
-
- Это нормально, не использовать `.catch`, если мы не знаем как обработать ошибку (невозможно исправить все ошибки).
303
-
- В любом случае нам следует использовать обработчик события `unhandledrejection` (для браузеров и аналог для других окружений), чтобы отслеживать необработанные ошибки и информировать об этом пользователя (и, возможно, наш сервер) о них, так что наше приложение никогда "не умрёт".
302
+
- Это нормально не использовать `.catch`, если мы не знаем как обработать ошибку (невозможно исправить все ошибки).
303
+
- В любом случае нам следует использовать обработчик события `unhandledrejection` (для браузеров и аналог для других окружений), чтобы отслеживать необработанные ошибки и информировать об этом пользователя (и, возможно, наш сервер) о них, так, чтобы наше приложение никогда не умирало.
304
304
305
-
И наконец, если у нас имеется индикатор загрузки, тогда `.finally` - отличный обработчик окончания загрузки, когда загрузка завершена:
305
+
И, наконец, если у нас имеется индикатор загрузки, тогда finally - это отличное место, чтобы остановить его, когда загрузка завершена:
0 commit comments