Пользовательские страницы ошибок

В React Router создание пользовательских страниц ошибок позволяет гибко управлять отображением ошибок маршрутизации, обеспечивая более дружелюбный и контролируемый интерфейс при возникновении проблем, таких как неправильные URL, недоступные ресурсы или ошибки загрузки компонентов. В современных версиях React Router (v6 и выше) основной подход основан на использовании элемента или атрибута errorElement для маршрутов.


Определение страницы ошибки

Страница ошибки — это обычный React-компонент, который рендерится при возникновении ошибки на конкретном маршруте. Ключевой момент — этот компонент получает объект ошибки через хук useRouteError, что позволяет детально управлять отображением информации о проблеме.

import { useRouteError } from "react-router-dom";

function ErrorPage() {
  const error = useRouteError();
  
  console.error(error);

  return (
    

Произошла ошибка

{error.statusText || error.message}

); }

Пояснение:

  • useRouteError возвращает объект ошибки маршрута.
  • Можно выводить как системные сообщения, так и пользовательские.
  • Консольное логирование полезно для отладки и анализа ошибок на стадии разработки.

Привязка страницы ошибки к маршрутам

Для того чтобы маршрут корректно использовал страницу ошибки, используется свойство errorElement:

import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./HomePage";
import AboutPage from "./AboutPage";
import ErrorPage from "./ErrorPage";

const router = createBrowserRouter([
  {
    path: "/",
    element: ,
    errorElement: 
  },
  {
    path: "/about",
    element: ,
    errorElement: 
  }
]);

function App() {
  return ;
}

Ключевые моменты:

  • errorElement может быть назначен как отдельному маршруту, так и вложенной группе маршрутов.
  • Если ошибка возникает в дочернем маршруте, она “поднимается” к ближайшему родителю, у которого определён errorElement.
  • Это обеспечивает гибкую структуру обработки ошибок на уровне всего приложения или отдельных страниц.

Обработка различных типов ошибок

React Router различает несколько типов ошибок:

  1. 404 Not Found – маршрут не найден.
  2. Ошибка загрузки данных – например, если используется loader для загрузки данных и запрос возвращает ошибку.
  3. Ошибка рендеринга – ошибки компонентов, отрисовываемых на маршруте.

Пример с обработкой загрузки данных через loader:

import { useRouteError } from "react-router-dom";

async function userLoader({ params }) {
  const response = await fetch(`/api/users/${params.userId}`);
  if (!response.ok) {
    throw new Response("Пользователь не найден", { status: 404 });
  }
  return response.json();
}

const router = createBrowserRouter([
  {
    path: "/users/:userId",
    element: ,
    loader: userLoader,
    errorElement: 
  }
]);

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

  • Ошибки Response автоматически передаются в компонент ошибки.
  • Это позволяет создать единый интерфейс для всех видов ошибок на странице.

Вложенные маршруты и обработка ошибок

Для вложенных маршрутов можно использовать каскадное определение страниц ошибок. Если дочерний маршрут вызывает ошибку, React Router ищет ближайший errorElement в иерархии.

const router = createBrowserRouter([
  {
    path: "/dashboard",
    element: ,
    errorElement: ,
    children: [
      {
        path: "settings",
        element: ,
        errorElement: 
      }
    ]
  }
]);

Важно:

  • Ошибка в SettingsPage будет обрабатываться SettingsErrorPage.
  • Если SettingsErrorPage отсутствует, то будет показан DashboardErrorPage.
  • Это позволяет создавать уровни изолированной обработки ошибок для больших приложений.

Пользовательская визуализация и UX

Страницы ошибок могут включать:

  • Кнопки для возврата на главную страницу или предыдущую страницу.
  • Ссылки на часто используемые маршруты.
  • Динамическое сообщение в зависимости от типа ошибки (404, 500 и т. д.).

Пример:

function ErrorPage() {
  const error = useRouteError();

  return (
    

Ошибка {error.status || "неизвестная"}

{error.statusText || error.message}

На главную
); }

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

Для улучшения поддержки и анализа приложений ошибки часто отправляются на сервер:

import { useEffect } from "react";
import { useRouteError } from "react-router-dom";

function ErrorPage() {
  const error = useRouteError();

  useEffect(() => {
    fetch("/api/log-error", {
      method: "POST",
      body: JSON.stringify({ message: error.message, stack: error.stack }),
      headers: { "Content-Type": "application/json" }
    });
  }, [error]);

  return (
    

Произошла ошибка

{error.statusText || error.message}

); }

Заметки:

  • Логирование ошибок на сервер позволяет отслеживать реальные проблемы пользователей.
  • Для производственной среды рекомендуется маскировать подробности ошибок на интерфейсе и оставлять их только в логах.

Советы по проектированию страниц ошибок

  • Использовать единый компонент ошибки для маршрутов с похожей логикой.
  • Разграничивать ошибки загрузки данных и рендеринга компонентов для более точной диагностики.
  • Сохранять консистентный стиль UI, чтобы страницы ошибок выглядели как часть приложения.
  • Поддерживать навигацию из страницы ошибки, чтобы пользователь не застревал на мертвой странице.