← Назад к вопросам

Какая граница ошибок используется на нынешней работе?

1.8 Middle🔥 141 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Границы ошибок (Error Boundaries) в React-приложениях

На проекте, где я работаю в качестве Senior Frontend Developer, мы активно используем Error Boundaries — механизм React для отлова и обработки JavaScript-ошибок в компонентах, чтобы предотвратить "падение" всего приложения. Это критически важная практика для обеспечения отказоустойчивости пользовательского интерфейса в продакшене.

Реализация Error Boundaries

Мы применяем два основных подхода:

  1. Классовые компоненты как Error Boundaries (стандартный способ, рекомендованный React).
    Создаём переиспользуемый компонент-обёртку, который использует жизненные циклы getDerivedStateFromError и componentDidCatch:
import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null, errorInfo: null };
  }

  static getDerivedStateFromError(error) {
    // Обновляем состояние для отображения запасного UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // Логируем ошибку в сервис мониторинга (например, Sentry)
    this.setState({ error, errorInfo });
    logErrorToMonitoringService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // Показываем запасной UI
      return (
        <div className="error-fallback">
          <h2>Что-то пошло не так</h2>
          <button onClick={() => window.location.reload()}>
            Обновить страницу
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}
  1. Использование React Error Boundary с хуками через библиотеку react-error-boundary.
    Это современный и более гибкий способ, который мы предпочитаем в новых компонентах:
import { ErrorBoundary } from 'react-error-boundary';

function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div role="alert">
      <p>Произошла ошибка:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Попробовать снова</button>
    </div>
  );
}

function App() {
  return (
    <ErrorBoundary
      FallbackComponent={ErrorFallback}
      onReset={() => {
        // Сброс состояния приложения
      }}
      onError={(error, errorInfo) => {
        // Отправка в Sentry/LogRocket
      }}
    >
      <ComponentThatMayError />
    </ErrorBoundary>
  );
}

Стратегия применения в проекте

На нашем проекте границы ошибок реализованы на нескольких уровнях:

  • На уровне маршрутов (routes) — каждый роут обёрнут в Error Boundary, чтобы ошибка в одном разделе не ломала всё приложение
  • Для критических UI-блоков — например, дашборды, таблицы с данными, формы заказов
  • Внутри лениво загружаемых компонентов — для обработки ошибок при динамическом импорте

Ключевые аспекты нашей реализации:

Мониторинг и логирование:
Все пойманные ошибки автоматически отправляются в:

  • Sentry для трекинга и анализа
  • Amplitude для корреляции с пользовательскими сессиями
  • Внутреннюю панель мониторинга для быстрого реагирования

Восстановление состояния:
Мы реализовали стратегии восстановления:

  • Кнопка повторной попытки для повторного рендера компонента
  • Автоматический сброс при смене маршрута
  • Сохранение состояния в localStorage для критических форм

Тестирование:
Error Boundaries покрыты unit-тестами:

import { render, screen, fireEvent } from '@testing-library/react';

test('ErrorBoundary shows fallback UI when error occurs', () => {
  const ThrowingComponent = () => {
    throw new Error('Test error');
  };

  render(
    <ErrorBoundary>
      <ThrowingComponent />
    </ErrorBoundary>
  );

  expect(screen.getByText(/Что-то пошло не так/i)).toBeInTheDocument();
});

Ограничения и best practices

Важно понимать, что Error Boundaries не ловят:

  • Ошибки в обработчиках событий
  • Асинхронный код (setTimeout, промисы)
  • Ошибки в самом Error Boundary
  • Ошибки серверного рендеринга

Для этих случаев у нас есть:

  • Try-catch в обработчиках событий
  • Глобальный обработчик ошибок window.onerror
  • Интерцепторы в HTTP-клиенте (axios/fetch)

Эволюция подхода

Изначально мы использовали только классовые Error Boundaries, но постепенно мигрируем к react-error-boundary из-за:

  • Более чистого API
  • Поддержки хуков
  • Встроенных возможностей reset и recovery
  • Активной поддержки сообществом

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

Такой многоуровневый подход к обработке ошибок позволяет нам поддерживать высокий уровень доступности приложения (99.9% uptime) и обеспечивать плавный пользовательский опыт даже при возникновении неожиданных проблем.