В TanStack Router управление состоянием маршрутов тесно связано с
загрузкой данных через loader функции. При работе с
асинхронными запросами неизбежно возникают ошибки: сетевые сбои,
некорректные ответы API, проблемы с авторизацией. TanStack Router
предоставляет инструменты для централизованной и удобной обработки таких
ошибок, позволяя отображать пользователю корректные состояния без ломки
приложения.
Каждый маршрут может содержать loader — асинхронную
функцию, которая возвращает данные для компонента маршрута:
import { createRouter, createRouteConfig } from '@tanstack/router';
const userRoute = {
path: '/users/:id',
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.id}`);
if (!response.ok) {
throw new Error(`Ошибка загрузки пользователя: ${response.status}`);
}
return response.json();
}
};
Если loader выбрасывает исключение, TanStack Router
автоматически передает управление в ближайший обработчик ошибок маршрута
(errorComponent). Исключения могут быть как синхронными
(throw new Error()), так и асинхронными (отклоненный
Promise).
TanStack Router поддерживает концепцию error boundaries,
аналогичную React. Каждый маршрут может содержать
errorComponent:
const UserError = ({ error }) => (
<div>
<h2>Не удалось загрузить пользователя</h2>
<p>{error.message}</p>
</div>
);
const userRoute = {
path: '/users/:id',
loader: async ({ params }) => { /* ... */ },
errorComponent: UserError
};
Если loader выбросит ошибку, TanStack Router рендерит
UserError вместо основного компонента. Ошибка передается
через проп error, что позволяет точно отобразить причину
сбоя.
Для сложных приложений удобно иметь глобальный обработчик ошибок,
который реагирует на все ошибки маршрутов. Это можно реализовать через
родительский маршрут с errorComponent:
const RootError = ({ error }) => (
<div>
<h1>Произошла ошибка</h1>
<p>{error.message}</p>
</div>
);
const rootRoute = {
path: '/',
children: [userRoute],
errorComponent: RootError
};
Ошибки дочерних маршрутов будут всплывать к родительскому
errorComponent, если у дочернего маршрута нет собственного
обработчика. Это позволяет централизовать логику отображения ошибок.
Ошибки могут быть классифицированы по типу:
Для различения ошибок можно использовать кастомные классы:
class NetworkError extends Error {}
class AuthError extends Error {}
const loader = async () => {
const res = await fetch('/api/data');
if (res.status === 401) throw new AuthError('Необходима авторизация');
if (!res.ok) throw new NetworkError('Ошибка сети');
return res.json();
};
В errorComponent можно проверять тип ошибки и рендерить
разные состояния:
const DataError = ({ error }) => {
if (error instanceof AuthError) return <div>Требуется вход</div>;
if (error instanceof NetworkError) return <div>Проблемы с сетью</div>;
return <div>Произошла неизвестная ошибка</div>;
};
TanStack Router поддерживает механизм повторной загрузки данных через
функцию retry. Например, можно предоставить пользователю
кнопку «Попробовать снова»:
const UserError = ({ error, retry }) => (
<div>
<p>{error.message}</p>
<button onCl ick={retry}>Попробовать снова</button>
</div>
);
Вызов retry повторно запускает loader,
позволяя восстановить данные без перезагрузки всего приложения.
SuspenseПри работе с асинхронными данными можно объединять
loader маршрутов с React Suspense. TanStack Router
позволяет интегрировать асинхронные компоненты и обрабатывать ошибки на
уровне маршрутов:
const UserComponent = React.lazy(() => import('./UserComponent'));
const userRoute = {
path: '/users/:id',
loader: async ({ params }) => fetch(`/api/users/${params.id}`).then(r => r.json()),
component: () => (
<React.Suspense fallback={<div>Загрузка...</div>}>
<UserComponent />
</React.Suspense>
),
errorComponent: UserError
};
Ошибки при динамическом импорте также будут перехвачены
errorComponent, что обеспечивает единообразную
обработку.
Для продакшн-приложений рекомендуется отправлять ошибки в систему
логирования или аналитики. Это делается в errorComponent
или через глобальный хендлер:
const RootError = ({ error }) => {
console.error(error);
// Можно отправить в Sentry, LogRocket и т.п.
return <div>Произошла ошибка. Попробуйте позже.</div>;
};
Поддержка асинхронного логирования позволяет собирать статистику по типам ошибок и местам их возникновения.
loader маршрута выбрасывает ошибки при сбое загрузки
данных.errorComponent маршрута отображает ошибку и может
предоставлять пользовательские действия (retry, переход).errorComponent при отсутствии локального обработчика.Эта модель обработки ошибок обеспечивает стабильность приложений на TanStack Router, позволяя надежно работать с асинхронными данными и предотвращать разрывы пользовательского интерфейса.