错误监控
- 使用React Error Boundaries:
- 在React应用中,错误边界是一种特殊的React组件,它可以捕获其子组件树中任何位置抛出的JavaScript错误,并记录这些错误,同时展示备用UI而不是崩溃的组件树。
- 例如:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, errorInfo) {
this.setState({ hasError: true });
// 记录错误,这里假设logError是自定义的日志记录函数
logError(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 返回备用UI
return <div>Something went wrong.</div>;
}
return this.props.children;
}
}
- 全局错误监听:
- 在应用的入口文件(如
index.js
)中,可以使用window.onerror
来捕获未被React错误边界捕获的全局JavaScript错误。
- 示例代码:
window.onerror = function (message, source, lineno, colno, error) {
// 记录错误,这里假设logGlobalError是自定义的日志记录函数
logGlobalError(message, source, lineno, colno, error);
return true;
};
错误上报
- 开发环境:
- 在开发环境,可以将错误信息打印到控制台,方便开发者快速定位问题。例如在
logError
或logGlobalError
函数中直接使用console.error
。
function logError(error, errorInfo) {
console.error('Component error:', error, errorInfo);
}
function logGlobalError(message, source, lineno, colno, error) {
console.error('Global error:', message, source, lineno, colno, error);
}
- 测试环境:
- 可以将错误信息发送到内部的测试日志服务器,便于测试团队分析问题。可以使用
fetch
或其他HTTP库将错误信息POST到服务器接口。
function logError(error, errorInfo) {
const errorData = {
error: error.message,
stack: error.stack,
errorInfo: errorInfo
};
fetch('/test - error - api', {
method: 'POST',
headers: {
'Content - Type': 'application/json'
},
body: JSON.stringify(errorData)
});
}
- 生产环境:
- 使用专业的错误监控服务,如Sentry。Sentry可以自动捕获JavaScript错误,并提供详细的错误堆栈信息、用户上下文等。引入Sentry SDK后,在
logError
和logGlobalError
函数中调用Sentry的捕获函数。
import * as Sentry from '@sentry/react';
function logError(error, errorInfo) {
Sentry.captureException(error, {
extra: {
errorInfo: errorInfo
}
});
}
function logGlobalError(message, source, lineno, colno, error) {
Sentry.captureException(error, {
extra: {
message,
source,
lineno,
colno
}
});
}
错误恢复
- 组件级别恢复:
- 对于React组件内的错误,错误边界的备用UI可以让应用保持可用状态。例如,上述
ErrorBoundary
组件在捕获到错误后展示简单的错误提示,用户可以继续与应用的其他部分交互。
- 全局错误恢复:
- 对于全局错误,尽量减少错误对应用其他部分的影响。例如,在
window.onerror
处理函数中返回true
,阻止浏览器默认的错误处理行为,避免页面崩溃。同时,可以尝试进行一些清理操作,如取消未完成的异步任务等。
与应用整体架构融合
- 模块边界设置错误边界:
- 在每个独立模块的入口处包裹错误边界组件,这样可以确保每个模块的错误不会影响其他模块。例如,如果有一个用户信息展示模块,可以在该模块的根组件外层包裹
ErrorBoundary
。
- 第三方组件处理:
- 对于第三方组件,可以先对其进行封装,在封装组件外层包裹错误边界。这样既可以捕获第三方组件可能抛出的错误,又可以对错误进行统一处理和展示备用UI。例如,封装一个第三方图表组件:
class ChartWrapper extends React.Component {
render() {
return (
<ErrorBoundary>
<ThirdPartyChartComponent {...this.props} />
</ErrorBoundary>
);
}
}
不同环境差异和优化方向
- 开发环境:
- 差异:主要关注错误的详细信息展示,以帮助开发者快速定位问题。错误上报主要是打印到控制台。
- 优化方向:可以增加更多的调试信息,如错误发生时组件的状态、props等,方便开发者更全面地了解错误发生的上下文。
- 测试环境:
- 差异:需要将错误信息发送到内部测试日志服务器,便于测试团队分析问题。错误监控和恢复机制与生产环境类似,但不需要考虑性能优化方面的极端情况。
- 优化方向:可以对错误进行分类统计,方便测试团队快速了解应用中各类错误的出现频率和分布情况,针对性地进行测试和修复。
- 生产环境:
- 差异:重点关注错误对用户体验的影响,需要使用专业的错误监控服务来确保错误得到及时处理。同时,要优化错误捕获和上报的性能,尽量减少对应用性能的影响。
- 优化方向:可以根据用户行为和错误发生的频率、严重程度等因素,对错误进行优先级排序,优先处理对用户体验影响较大的错误。并且可以结合用户反馈进一步优化错误监控和恢复策略。