Files
WhiteNightsAdminPanel/src/app/GlobalErrorBoundary.tsx
2025-10-02 22:20:37 +03:00

159 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { Component, ReactNode } from "react";
import { Box, Button, Typography, Paper, Container } from "@mui/material";
import { RefreshCw, Home, AlertTriangle } from "lucide-react";
interface Props {
children: ReactNode;
}
interface State {
hasError: boolean;
error: Error | null;
}
export class GlobalErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
hasError: false,
error: null,
};
}
static getDerivedStateFromError(error: Error): State {
return {
hasError: true,
error,
};
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.error("❌ GlobalErrorBoundary: Критическая ошибка приложения", {
error: error.message,
stack: error.stack,
componentStack: errorInfo.componentStack,
});
}
handleReset = () => {
this.setState({
hasError: false,
error: null,
});
window.location.reload();
};
handleGoHome = () => {
this.setState({
hasError: false,
error: null,
});
window.location.href = "/";
};
render() {
if (this.state.hasError) {
return (
<Box
sx={{
minHeight: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "background.default",
p: 2,
}}
>
<Container maxWidth="sm">
<Paper
elevation={3}
sx={{
p: 4,
textAlign: "center",
}}
>
<Box
sx={{
display: "flex",
justifyContent: "center",
mb: 3,
}}
>
<AlertTriangle size={64} color="#f44336" />
</Box>
<Typography variant="h4" component="h1" gutterBottom>
Упс! Что-то пошло не так
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
Приложение столкнулось с неожиданной ошибкой. Попробуйте
перезагрузить страницу или вернуться на главную.
</Typography>
{this.state.error?.message && (
<Paper
variant="outlined"
sx={{
p: 2,
mb: 3,
backgroundColor: "error.light",
color: "error.contrastText",
textAlign: "left",
}}
>
<Typography
variant="caption"
sx={{ fontWeight: "bold", display: "block", mb: 1 }}
>
Информация об ошибке:
</Typography>
<Typography
variant="caption"
sx={{
fontFamily: "monospace",
fontSize: "0.75rem",
wordBreak: "break-word",
display: "block",
}}
>
{this.state.error.message}
</Typography>
</Paper>
)}
<Box
sx={{
display: "flex",
gap: 2,
justifyContent: "center",
flexWrap: "wrap",
}}
>
<Button
variant="outlined"
startIcon={<Home size={16} />}
onClick={this.handleGoHome}
size="large"
>
На главную
</Button>
<Button
variant="contained"
startIcon={<RefreshCw size={16} />}
onClick={this.handleReset}
size="large"
>
Перезагрузить
</Button>
</Box>
</Paper>
</Container>
</Box>
);
}
return this.props.children;
}
}