Логирование ошибок

TanStack Router предоставляет гибкие инструменты для маршрутизации в приложениях на JavaScript и TypeScript. Важной частью стабильной работы приложения является корректная обработка и логирование ошибок, возникающих на уровне маршрутов, загрузчиков данных или компонентов.

Перехват ошибок на уровне маршрута

Каждый маршрут в TanStack Router может содержать собственный обработчик ошибок через свойство errorComponent или onError. Это позволяет централизованно управлять поведением при возникновении исключений.

Пример использования errorComponent:

import { Router, Route } from '@tanstack/router';
import ErrorPage from './ErrorPage';
import HomePage from './HomePage';

const router = new Router({
  routes: [
    new Route({
      path: '/',
      component: HomePage,
      errorComponent: ErrorPage
    }),
  ],
});

Особенности:

  • errorComponent отображается вместо обычного компонента при ошибке на этом маршруте.
  • Можно определить отдельные errorComponent для дочерних маршрутов, чтобы логика обработки ошибок была изолирована.

Глобальный обработчик ошибок

Для глобального логирования всех ошибок можно использовать router.subscribe с проверкой событий ошибок:

router.subscribe((state) => {
  if (state.latestError) {
    console.error('Произошла ошибка маршрутизации:', state.latestError);
    // Можно отправить данные на сервер мониторинга
  }
});

Преимущество такого подхода — единое место для логирования ошибок, независимо от уровня маршрута.

Обработка ошибок в загрузчиках данных (Loaders)

TanStack Router поддерживает асинхронные загрузчики данных для маршрутов. Любые исключения, возникающие внутри загрузчика, автоматически передаются в errorComponent маршрута. Для логирования можно обернуть загрузчик в try/catch:

const userLoader = async ({ params }) => {
  try {
    const response = await fetch(`/api/users/${params.userId}`);
    if (!response.ok) throw new Error('Не удалось загрузить данные пользователя');
    return response.json();
  } catch (error) {
    console.error('Ошибка загрузки пользователя:', error);
    throw error; // проброс ошибки в маршрут
  }
};

Ключевой момент: проброс ошибки важен для корректного отображения errorComponent.

Логирование ошибок компонентов

Ошибки, возникающие непосредственно внутри React-компонентов, подключённых к маршрутам, также можно отслеживать с помощью Error Boundary компонентов. TanStack Router позволяет интегрировать их напрямую с маршрутом:

import { ErrorBoundary } from 'react-error-boundary';

const UserPage = ({ user }) => {
  if (!user) throw new Error('Пользователь не найден');
  return <div>{user.name}</div>;
};

const ErrorFallback = ({ error }) => {
  console.error('Ошибка компонента:', error);
  return <div>Произошла ошибка при загрузке страницы.</div>;
};

<Route
  path="/user/:userId"
  component={() => (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <UserPage />
    </ErrorBoundary>
  )}
/>

Интеграция с системами мониторинга

Для крупных приложений важно не только выводить ошибки в консоль, но и отправлять их в системы мониторинга, такие как Sentry, LogRocket или собственные серверные сервисы. Логирование ошибок маршрутизации может быть централизовано через глобальный подписчик router.subscribe или внутри ErrorBoundary:

router.subscribe((state) => {
  if (state.latestError) {
    sendToMonitoringService(state.latestError);
  }
});

function sendToMonitoringService(error) {
  fetch('/api/log-error', {
    method: 'POST',
    body: JSON.stringify({ message: error.message, stack: error.stack }),
  });
}

Важные моменты при логировании

  1. Разделение типов ошибок — отличать ошибки загрузчиков данных, компонентов и внутренних ошибок маршрутизации.
  2. Прозрачность для пользователяerrorComponent должен отображать понятное сообщение, не раскрывая внутренние детали системы.
  3. Централизованное хранение — все ошибки, требующие анализа, должны отправляться в единую систему логирования.
  4. Асинхронная обработка — ошибки в загрузчиках и API-запросах должны учитываться отдельно, чтобы не блокировать маршрутизацию.

Совместное использование с TypeScript

TypeScript позволяет строго типизировать загрузчики данных и параметры маршрутов, что снижает вероятность ошибок на этапе компиляции. Например:

type UserParams = { userId: string };

const userLoader: LoaderFunction<UserParams, User> = async ({ params }) => {
  if (!params.userId) throw new Error('Не указан userId');
  const response = await fetch(`/api/users/${params.userId}`);
  if (!response.ok) throw new Error('Ошибка загрузки данных пользователя');
  return response.json();
};

Типизация повышает надёжность и позволяет заранее отлавливать многие ошибки до выполнения кода.

Вывод

Эффективное логирование ошибок в TanStack Router строится на сочетании нескольких уровней: локальные errorComponent, глобальные подписчики router.subscribe, обработка ошибок в загрузчиках и интеграция с системами мониторинга. Такой подход обеспечивает как прозрачное отображение ошибок пользователю, так и централизованное отслеживание для команды разработки.