Как обрабатывать необработанные ошибки отказа с помощью axios
Axios - отличная библиотека, но необработанные отказы от обещаний могут стать проблемой. Как от них избавиться?
TL;DR
Используйте этот перехватчик:
axios.interceptors.response.use( response => response, error => { throw error } )
Предыстория
Я сегодня просматривал свои отчеты об ошибках на Honeybadger и наткнулся на следующее:
Если вы похожи на меня, вы смотрите на это мышление ... Хорошо, но что пошло не так? Что касается Honeybadger, ошибка заключается в том, что мы не обработали отказ от обещания. Однако настоящая проблема в том, что axios отклонены из-за неудавшегося запроса. К сожалению, мы не можем сказать, в чем заключалась ошибка, потому что она скрыта за этой unhandledrejection
ошибкой.
Что такое принятое решение?
Я пошел искать решение и наткнулся на эту проблему Github, которая привела меня на верный путь.
Svpace упомянул, что они использовали этот перехватчик:
axios.interceptors.response.use( response => response, error => { console.log(error.message); return Promise.reject(error); }
но это не сработало, как они ожидали. Они все еще сталкивались с unhandledrejection
ошибкой.
Я попытался использовать этот перехватчик и увидел точно такой же результат, что и они, что имеет смысл.
Почему это не работает?
Если вы посмотрите на перехватчик, мы обрабатываем отказ. В этом обработчике мы записываем сообщение об ошибке и переходим к следующему этапу. К сожалению, следующее, что делает перехватчик, - это еще один отказ. Этот отказ возвращает нас с того места, где мы начали, с необработанным отказом.
Код
Ваши запросы axios должны выглядеть следующим образом:
const response = await axios.get("/some/path/or/url").catch(yourErrorHandler)
or
try { const response = await axios.get("/some/path/or/url") } catch (e) { yourErrorHandler(e) }
Мой обработчик ошибок выглядит так:
export function handleError(e) { if (typeof Honeybadger !== "undefined") { Honeybadger.notify(e) } else { throw e } }
Кроме того, я использую try
/ catch
версию приведенного выше кода.
Исходя из этого, вы можете видеть, что мой axios.get
вызов завершился неудачно, а e
в блоке catch - это unhandledrejection
ошибка, а не обнаруженные аксиомы ошибки. Затем об этой ошибке сообщается Honeybadger.
Какое решение подойдет нам?
Как я уже упоминал, проблема с Github поставила меня на верный путь. Мы определенно хотим использовать перехватчик, поскольку это единственный известный мне способ справиться с отказом. А как же должен выглядеть наш перехватчик?
Во-первых, мы хотим передать успешные решения, поэтому начнем с этого:
axios.interceptors.response.use(response => response)
Далее нам нужно добавить обработчик отклонения:
axios.interceptors.response.use( response => response, error => {} )
Что нам делать в этом обработчике? Давайте подумаем о наших целях:
- Избавьтесь от ошибки
unhandledrejection
. - Выявите фактическую ошибку в нашем
Promise.catch
вызове или в блокеcatch
, если вы используете_11 _ / _ 12_.
Способ сделать это - повторно выбросить исходную ошибку, а не отклонять ее снова. Для этого мы можем обновить перехватчик, чтобы он выглядел так:
axios.interceptors.response.use( response => response, error => { // We really want to throw the error so it is handled and we // don't get an unhandledrejection error. By throwing here, we // are handling the rejection, and bubbling up to the closest // error handler (try/catch or catch method call on a promise). throw error } )
Спасибо за чтение, друг
Надеюсь, вам понравилась эта статья, удачного дня!
Первоначально опубликовано на https://brandoncc.dev.