У меня возникли некоторые проблемы при попытке понять следующий код в упражнении, касающемся обработки ошибок:
const getSuggestions = () => {
const wordQuery = inputField.value;
const endpoint = url + wordQuery;
fetch(endpoint, {cache: 'no-cache'})
.then(response => {
if (response.ok) {
return response.json();
} throw new Error('Request failed!');
}, networkError => {
console.info(networkError.message);
})
}
Мой вопрос: почему мы ловим здесь ошибки два раза? Один раз, используя throw new Error
, и один раз, добавляя второй аргумент networkError
в .then()
? Они ловят одну и ту же ошибку и, следовательно, избыточны?
Как это будет выглядеть, если мы используем здесь try...catch...
?
Решено:
Обещание, возвращаемое fetch(), всегда разрешается, если HTTP-запрос завершается, не имеет значения, есть ли ошибка состояния HTTP. В первом аргументе блока then() мы обрабатываем ошибки HTTP. Обещание будет отклонено при возникновении сетевой ошибки, не связанной со статусом HTTP. В этом случае мы должны обработать сценарий отклонения со вторым аргументом в then().
Вместо того, чтобы редактировать свой вопрос, чтобы добавить раздел «решено», рассмотрите возможность принять один из ответов или ответить самому себе
Потому что fetch будет выдавать ошибку только при сетевых ошибках, а не при кодах состояния ошибок, таких как 404.
В этом фрагменте кто-то проверил, был ли ответ равен 200, и если нет, добавил «пользовательскую» ошибку с помощью throw.
Это эквивалентный код, но, надеюсь, более понятный
fetch(endpoint, {cache: 'no-cache'})
.catch(networkError => {
console.info(networkError.message);
return 'networkError'
})
.then(response => {
if (response == 'networkError') return;
if (response.ok) {
return response.json();
} else {
throw new Error('Request failed!');
}
})
Необходимость делать if (response == 'networkError') return;
кажется намного более сложной, чем использование .then()
с двумя аргументами, но да, это эквивалентно
2 механизма ошибок имеют дело с разными типами ошибок:
if (!response.ok) обрабатывает http-ответы сервера для статусов ответов http 4xx и 5xx. Вызов достиг http-сервера, и он ответил.
networkError => { предназначен для ошибок, возникающих даже до того, как они достигают сервера, возможно, даже достигают сети.
Они очень разные, управляются по-разному.
throw
не ловит ошибки...