Мониторинг ошибок

Современные веб-приложения обладают сложной архитектурой: асинхронные запросы, большое количество пользовательских взаимодействий, состояние компонентов и динамическая отрисовка интерфейса. В таких условиях ошибки могут возникать на разных уровнях: от проблем в рендеринге компонентов до некорректной обработки данных из API.

Мониторинг ошибок позволяет:

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

При использовании библиотеки Material UI (MUI) особое внимание уделяется корректной обработке ошибок в компонентах, визуальному отображению проблем и интеграции с системами отслеживания ошибок.


Типы ошибок в приложениях с MUI

Ошибки в интерфейсах на базе React и MUI можно условно разделить на несколько категорий.

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

Возникают во время построения виртуального DOM. Причины:

  • некорректные пропсы;
  • попытка обращения к undefined;
  • ошибки в пользовательских хуках;
  • исключения в функциях рендера.

Пример:

function Profile({ user }) {
  return <Typography>{user.name.toUpperCase()}</Typography>;
}

Если user равен undefined, приложение выбросит исключение.


Ошибки асинхронных операций

Такие ошибки возникают при работе с API, загрузке данных или при использовании async/await.

Пример:

async function loadUsers() {
  const response = await fetch("/api/users");
  const data = await response.json();
  return data;
}

Возможные проблемы:

  • сетевые ошибки;
  • некорректный формат ответа;
  • ошибки авторизации.

Ошибки состояния интерфейса

Иногда ошибки связаны с неправильным управлением состоянием.

Например:

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

Использование Error Boundary

React предоставляет механизм Error Boundary — специальные компоненты, которые перехватывают ошибки в дочерних компонентах.

Это основной инструмент мониторинга ошибок на уровне интерфейса.

Базовая реализация

import React from "react";
import { Alert, AlertTitle } from "@mui/material";

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    console.error("UI error:", error, info);
  }

  render() {
    if (this.state.hasError) {
      return (
        <Alert severity="error">
          <AlertTitle>Ошибка интерфейса</AlertTitle>
          Не удалось отобразить компонент
        </Alert>
      );
    }

    return this.props.children;
  }
}

Компонент:

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

Оборачивание компонентов

Error Boundary используется как контейнер.

<ErrorBoundary>
  <UserProfile />
</ErrorBoundary>

Если внутри UserProfile произойдет ошибка, приложение не упадет полностью — будет показано сообщение об ошибке.


Визуальное отображение ошибок с помощью MUI

Material UI предоставляет множество компонентов, позволяющих корректно отображать ошибки в интерфейсе.

Alert

Компонент Alert используется для информирования пользователя о проблемах.

import { Alert } from "@mui/material";

<Alert severity="error">
  Произошла ошибка загрузки данных
</Alert>

Возможные уровни:

  • error
  • warning
  • info
  • success

Alert с заголовком

import { Alert, AlertTitle } from "@mui/material";

<Alert severity="error">
  <AlertTitle>Ошибка</AlertTitle>
  Не удалось загрузить данные
</Alert>

Это повышает читаемость сообщений и делает интерфейс более структурированным.


Snackbar для уведомлений об ошибках

Snackbar используется для кратковременных уведомлений.

import { Snackbar, Alert } from "@mui/material";
import { useState } from "react";

function ErrorNotification() {
  const [open, setOpen] = useState(true);

  return (
    <Snackbar open={open} autoHideDuration={6000}>
      <Alert severity="error">
        Ошибка соединения с сервером
      </Alert>
    </Snackbar>
  );
}

Такой подход удобен для ненавязчивых уведомлений.


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

Отображение ошибки пользователю — только часть задачи. Важна фиксация ошибок для дальнейшего анализа.

Логирование в консоль

Минимальный вариант:

componentDidCatch(error, info) {
  console.error(error);
  console.error(info.componentStack);
}

Однако в production-среде этого недостаточно.


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

На практике используются специализированные сервисы.

Популярные системы:

  • Sentry
  • LogRocket
  • Bugsnag
  • Datadog

Они позволяют:

  • собирать стек ошибок;
  • фиксировать состояние приложения;
  • отслеживать действия пользователя перед ошибкой.

Пример интеграции с Sentry

Установка:

npm install @sentry/react

Инициализация:

import * as Sentry from "@sentry/react";

Sentry.init({
  dsn: "https://example@sentry.io/project-id",
});

Использование Error Boundary от Sentry:

<Sentry.ErrorBoundary fallback={<ErrorFallback />}>
  <App />
</Sentry.ErrorBoundary>

Создание пользовательского экрана ошибки

В сложных приложениях часто создается отдельный компонент для отображения критических ошибок.

Пример:

import { Box, Typography, Button } from "@mui/material";

function ErrorScreen({ onRetry }) {
  return (
    <Box
      display="flex"
      flexDirection="column"
      alignItems="center"
      justifyContent="center"
      height="100vh"
      gap={2}
    >
      <Typography variant="h4">
        Что-то пошло не так
      </Typography>

      <Typography color="text.secondary">
        Произошла непредвиденная ошибка приложения
      </Typography>

      <Button variant="contained" onCl ick={onRetry}>
        Попробовать снова
      </Button>
    </Box>
  );
}

Такой экран:

  • информирует пользователя;
  • позволяет повторить действие;
  • предотвращает отображение сломанного интерфейса.

Обработка ошибок форм

Ошибки часто возникают при работе с пользовательскими формами.

Material UI предоставляет встроенные средства отображения ошибок.

TextField с ошибкой

import { TextField } from "@mui/material";

<TextField
  label="Email"
  error={true}
  helperText="Неверный формат email"
/>

Свойства:

  • error — включает визуальное состояние ошибки;
  • helperText — отображает сообщение.

Валидация формы

Пример простой проверки:

const [email, setEmail] = useState("");
const [error, setError] = useState(false);

function handleSubmit() {
  if (!email.includes("@")) {
    setError(true);
  }
}

Использование:

<TextField
  label="Email"
  value={email}
  onCha nge={(e) => setEmail(e.target.value)}
  error={error}
  helperText={error ? "Введите корректный email" : ""}
/>

Обработка ошибок загрузки данных

Ошибки API должны корректно отображаться в интерфейсе.

Типичный паттерн:

const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);

Загрузка:

useEffect(() => {
  fetch("/api/users")
    .then((res) => res.json())
    .then(setData)
    .catch(setError)
    .finally(() => setLoading(false));
}, []);

Отображение:

if (loading) return <CircularProgress />;

if (error)
  return (
    <Alert severity="error">
      Ошибка загрузки данных
    </Alert>
  );

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

В крупных приложениях создается централизованная система обработки ошибок.

Контекст ошибок

const ErrorContext = React.createContext();

Провайдер:

function ErrorProvider({ children }) {
  const [error, setError] = useState(null);

  return (
    <ErrorContext.Provider value={{ error, setError }}>
      {children}
    </ErrorContext.Provider>
  );
}

Использование:

const { setError } = useContext(ErrorContext);

try {
  await apiCall();
} catch (e) {
  setError(e);
}

Отображение ошибки можно вынести в отдельный компонент уведомлений.


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

Централизованная обработка

Все ошибки должны проходить через единый механизм логирования.


Минимизация падений интерфейса

Использование Error Boundary вокруг ключевых частей интерфейса:

  • страниц
  • крупных виджетов
  • сложных компонентов

Информативные сообщения

Сообщения об ошибках должны:

  • быть понятными;
  • не раскрывать внутреннюю структуру приложения;
  • содержать рекомендации для пользователя.

Разделение пользовательских и системных ошибок

Важно различать:

  • ошибки пользователя (неверный ввод);
  • системные ошибки (сбой сервера).

Отображение должно отличаться.


Мониторинг в production

Ошибки, возникающие у пользователей, часто отличаются от ошибок во время разработки. Поэтому обязательно использование систем сбора ошибок в production-окружении.


Архитектура обработки ошибок в крупных приложениях

Типичная архитектура включает несколько уровней:

  1. Error Boundary — защита компонентов.
  2. UI-уведомления — отображение ошибок пользователю.
  3. Сервис логирования — отправка данных на сервер.
  4. Система мониторинга — анализ и агрегирование ошибок.

Такой многоуровневый подход обеспечивает:

  • устойчивость интерфейса;
  • быструю диагностику проблем;
  • улучшение пользовательского опыта.