1. 核心功能
- 捕获 JavaScript 运行时错误(
window.onerror
)。 - 捕获资源加载失败(
<img>
,<script>
,<link>
等)。 - 捕获未处理的 Promise 拒绝(
unhandledrejection
)。 - 捕获框架级别的错误(如 React、Vue 的错误边界)。
- 性能优化:避免监控代码本身引发性能问题。
- 扩展性:支持自定义错误处理逻辑。
2. 代码实现
javascript
复制
class ErrorMonitor {
constructor() {
this.init();
}
// 初始化监控
init() {
this.setupGlobalErrorHandlers();
this.setupResourceErrorHandlers();
this.setupPromiseRejectionHandlers();
}
// 捕获全局 JavaScript 运行时错误
setupGlobalErrorHandlers() {
window.onerror = (message, source, lineno, colno, error) => {
const errorInfo = {
type: 'runtime',
message: message,
source: source,
lineno: lineno,
colno: colno,
stack: error ? error.stack : null,
timestamp: new Date().toISOString()
};
this.handleError(errorInfo);
// 返回 true 阻止默认错误处理
return true;
};
}
// 捕获资源加载失败
setupResourceErrorHandlers() {
window.addEventListener('error', (event) => {
const target = event.target;
if (target && (target.tagName === 'IMG' || target.tagName === 'SCRIPT' || target.tagName === 'LINK')) {
const resourceErrorInfo = {
type: 'resource',
tagName: target.tagName,
src: target.src || target.href,
message: event.message,
timestamp: new Date().toISOString()
};
this.handleError(resourceErrorInfo);
}
}, true); // 使用捕获阶段监听
}
// 捕获未处理的 Promise 拒绝
setupPromiseRejectionHandlers() {
window.addEventListener('unhandledrejection', (event) => {
const promiseErrorInfo = {
type: 'promise',
reason: event.reason,
message: event.reason?.message || 'Unhandled promise rejection',
timestamp: new Date().toISOString()
};
this.handleError(promiseErrorInfo);
});
}
// 处理错误(可扩展)
handleError(errorInfo) {
// 这里可以添加自定义的错误处理逻辑
// 例如:过滤错误、格式化错误信息、触发回调等
console.error('Captured Error:', errorInfo);
// 如果需要扩展,可以触发事件或调用插件
if (this.onError) {
this.onError(errorInfo);
}
}
// 注册自定义错误处理函数
onError(callback) {
if (typeof callback === 'function') {
this.onError = callback;
}
}
}
// 初始化异常监控
const errorMonitor = new ErrorMonitor();
// 示例:自定义错误处理
errorMonitor.onError((errorInfo) => {
console.log('Custom Error Handler:', errorInfo);
});
3. 功能扩展
支持 React 错误边界
React 提供了错误边界(Error Boundary)机制,可以捕获组件树中的 JavaScript 错误。我们可以将其集成到监控系统中。
javascript
复制
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 将 React 错误信息传递给监控系统
errorMonitor.handleError({
type: 'react',
message: error.message,
stack: error.stack,
componentStack: errorInfo.componentStack,
timestamp: new Date().toISOString()
});
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
支持 Vue 错误处理
Vue 提供了全局错误处理钩子 errorHandler
,可以捕获 Vue 组件中的错误。
javascript
复制
Vue.config.errorHandler = (error, vm, info) => {
errorMonitor.handleError({
type: 'vue',
message: error.message,
stack: error.stack,
component: vm?.$options?.name,
lifecycleHook: info,
timestamp: new Date().toISOString()
});
};
4. 性能优化
- 避免阻塞主线程:错误处理逻辑应尽量轻量,避免同步操作。
- 采样率控制:在高并发场景下,可以通过采样率控制减少监控数据量。
- 懒加载监控代码:将监控代码拆分为独立模块,按需加载。
5. 总结
这个企业级前端异常监控方案具有以下特点:
- 全面性:覆盖 JavaScript 运行时错误、资源加载失败、Promise 拒绝、React/Vue 框架错误。
- 扩展性:支持自定义错误处理逻辑,方便集成到现有系统中。
- 高性能:避免监控代码本身成为性能瓶颈。
- 易用性:提供清晰的 API,支持自定义错误处理函数。