Современные веб-приложения обладают сложной архитектурой: асинхронные запросы, большое количество пользовательских взаимодействий, состояние компонентов и динамическая отрисовка интерфейса. В таких условиях ошибки могут возникать на разных уровнях: от проблем в рендеринге компонентов до некорректной обработки данных из API.
Мониторинг ошибок позволяет:
При использовании библиотеки Material UI (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;
}
Возможные проблемы:
Иногда ошибки связаны с неправильным управлением состоянием.
Например:
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 произойдет ошибка, приложение не
упадет полностью — будет показано сообщение об ошибке.
Material UI предоставляет множество компонентов, позволяющих корректно отображать ошибки в интерфейсе.
Компонент Alert используется для информирования
пользователя о проблемах.
import { Alert } from "@mui/material";
<Alert severity="error">
Произошла ошибка загрузки данных
</Alert>
Возможные уровни:
errorwarninginfosuccessimport { Alert, AlertTitle } from "@mui/material";
<Alert severity="error">
<AlertTitle>Ошибка</AlertTitle>
Не удалось загрузить данные
</Alert>
Это повышает читаемость сообщений и делает интерфейс более структурированным.
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-среде этого недостаточно.
На практике используются специализированные сервисы.
Популярные системы:
Они позволяют:
Установка:
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 предоставляет встроенные средства отображения ошибок.
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-окружении.
Типичная архитектура включает несколько уровней:
Такой многоуровневый подход обеспечивает: