Files
vf_react/src/components/ErrorBoundary.js
2025-10-24 16:40:26 +08:00

107 lines
4.2 KiB
JavaScript
Executable File
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 from 'react';
import {
Box,
Alert,
AlertIcon,
AlertTitle,
AlertDescription,
Button,
VStack,
Container
} from '@chakra-ui/react';
import { logger } from '../utils/logger';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// 所有环境都捕获错误,避免无限重渲染
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 记录详细的错误日志
logger.error('ErrorBoundary', 'Component Error Caught', error, {
componentStack: errorInfo.componentStack,
errorName: error.name,
errorMessage: error.message,
environment: process.env.NODE_ENV,
stack: error.stack
});
// 保存错误信息到 state
this.setState({
error: error,
errorInfo: errorInfo
});
}
render() {
// 如果有错误,显示错误边界(所有环境)
if (this.state.hasError) {
return (
<Container maxW="lg" py={20}>
<VStack spacing={6}>
<Alert status="error" borderRadius="lg" p={6}>
<AlertIcon boxSize="24px" />
<Box>
<AlertTitle fontSize="lg" mb={2}>
页面出现错误
</AlertTitle>
<AlertDescription>
{process.env.NODE_ENV === 'development'
? '组件渲染时发生错误,请查看下方详情和控制台日志。'
: '页面加载时发生了未预期的错误,请尝试刷新页面。'}
</AlertDescription>
</Box>
</Alert>
{/* 开发环境显示详细错误信息 */}
{process.env.NODE_ENV === 'development' && this.state.error && (
<Box
w="100%"
bg="red.50"
p={4}
borderRadius="lg"
fontSize="sm"
overflow="auto"
maxH="400px"
border="1px"
borderColor="red.200"
>
<Box fontWeight="bold" mb={2} color="red.700">错误详情:</Box>
<Box as="pre" whiteSpace="pre-wrap" color="red.900" fontSize="xs">
<Box fontWeight="bold" mb={1}>{this.state.error.name}: {this.state.error.message}</Box>
{this.state.error.stack && (
<Box mt={2} color="gray.700">{this.state.error.stack}</Box>
)}
{this.state.errorInfo && this.state.errorInfo.componentStack && (
<>
<Box fontWeight="bold" mt={3} mb={1} color="red.700">组件堆栈:</Box>
<Box color="gray.700">{this.state.errorInfo.componentStack}</Box>
</>
)}
</Box>
</Box>
)}
<Button
colorScheme="blue"
size="lg"
onClick={() => window.location.reload()}
>
重新加载页面
</Button>
</VStack>
</Container>
);
}
return this.props.children;
}
}
export default ErrorBoundary;