Как проверить и обработать ошибку из поля error в ответе API для корректного отображения
Что проверяют
Знаете ли вы, где fetch считает запрос ошибкой, а где нет, и умеете ли превратить разнородные ответы бэкенда в понятное пользователю сообщение. Следом обычно спрашивают, как вы показываете ошибки валидации отдельных полей формы.
Как отвечать
Опорные факты:
fetchне падает на 4xx и 5xx: промис отклоняется только при сетевой ошибке или отмене. Статус проверяют сами черезresponse.ok;- axios наоборот: по умолчанию бросает исключение на любом статусе вне 2xx, тело ошибки лежит в
error.response.data; - ошибка бывает и при 200: некоторые API отдают
{ "error": ... }с успешным статусом, GraphQL кладёт массивerrorsрядом сdata. Поэтому полеerrorпроверяют независимо от кода; - тело может быть не JSON: прокси на 502 вернёт HTML, и
response.json()бросит исключение. Сначала смотрятContent-Type.
Хорошая архитектура: один клиентский слой разбирает ответ и бросает свой ApiError со status, code, message и fields. Компоненты не знают, как устроен ответ, и работают с одним типом. Если бэкенд следует RFC 9457 (Problem Details, application/problem+json), разбор ещё проще.
Отображение:
- по стабильному
codeвыбирается своя фраза из словаря, сырой текст сервера идёт только запасным вариантом; - ошибки полей уходят в форму, например через
setErrorв react-hook-form, общие показываются тостом или блоком над формой; AbortErrorпри уходе со страницы не показывается вовсе;- в Sentry уходит ошибка со
status,codeи адресом запроса, но без персональных данных.
В TanStack Query всё это ложится в queryFn: бросили ApiError, компонент получил его в error.
Где спотыкаются
Пишут throw new Error(err.error), когда error это объект. В сообщении оказывается [object Object].
Выводят текст ошибки через innerHTML или dangerouslySetInnerHTML. Строку из ответа сервера нельзя вставлять как разметку.
Ждут, что error boundary в React поймает ошибку запроса. Он ловит ошибки рендера, а исключения из обработчиков событий и асинхронного кода туда сами не попадают.