Как обработать ошибку загрузки данных в компоненте и показать сообщение пользователю
Что проверяют
Различаете ли вы виды ошибок и умеете ли довести их до понятного интерфейса, а не до пустого экрана. Следом обычно спрашивают, поймает ли такую ошибку Error Boundary и что будет, если пользователь уйдёт со страницы до ответа.
Как отвечать
Опишите состояние как три взаимоисключающих варианта: загрузка, ошибка, данные. В TypeScript это размеченное объединение вида { status: "error"; error: Error }, и спиннер с ошибкой одновременно уже не показать.
Дальше конкретика:
response.ok:fetchотклоняет промис только при сетевом сбое, ответы 404 и 500 приходят как успешные. Статус проверяете и ошибку бросаете вы;- отмена:
AbortControllerвuseEffectиcontroller.abort()в очистке. Поздний ответ не перезапишет состояние, аAbortErrorне показывается как ошибка; - текст для человека: «Не удалось загрузить заказы» и кнопка «Повторить», технические детали уходят в Sentry. Контейнер помечается
role="alert", чтобы скринридер его озвучил; - старые данные: если упала повторная загрузка, лучше оставить прежние данные и показать уведомление, чем стереть экран;
- TanStack Query:
isError,error,refetchи по умолчанию три повтора с растущей задержкой на клиенте. ОпцияthrowOnErrorпередаёт ошибку ближайшему Error Boundary; - Error Boundary: ловит ошибки рендера. Сброс и повтор удобно делать через
react-error-boundaryиresetErrorBoundary, в Next.js App Router ту же роль играетerror.tsx.
Где спотыкаются
Не проверяют response.ok, парсят HTML-страницу ошибки как JSON и получают SyntaxError вместо внятного сообщения о статусе.
Считают, что Error Boundary сам поймает ошибку из useEffect или обработчика клика. Он ловит только брошенное во время рендера, асинхронную ошибку нужно положить в состояние или передать через библиотеку.
Показывают err.message как есть, например «Failed to fetch», и не сбрасывают ошибку перед повтором. Сообщение висит и после успешной загрузки.