当前位置: 首页 > news >正文

前端错误捕获

前端错误捕获

  • 一、怎么做错误捕获
    • 1.同步错误捕获
    • 2.异步错误捕获
    • 3.全局错误捕获
    • 4.框架层错误捕获
    • 5.资源加载错误
  • 二、JS有多少种错误类型
    • 1.ECMAScript标准错误
    • 2.浏览器特定错误
    • 3.自定义错误
  • 三、如何做统一的错误处理
    • 1. 在项目中实现外层统一错误处理
    • 2.错误分级策略
    • 3.监控能力
  • 四、异常监控工具
    • - 常见的监控工具
    • - 以React为例,如何使用Sentry进行前端异常监控和处理
          • 1.安装依赖
          • 2.初始化(入口文件)
          • 3. 全局错误边界
          • 4.异步操作错误捕获
          • 5. 路由追踪
          • 6. 自定义用户上下文

一、怎么做错误捕获

直入主题,以下是错误捕获的几种方法

1.同步错误捕获

try…catch

2.异步错误捕获

Promise/catch 与 async/await

  • Promise 链:通过 .catch() 处理拒绝状态
  • async/await + try…catch:更接近同步写法

3.全局错误捕获

window.onerror 与 unhandledrejection

  • ① window.onerror:捕获未被 try…catch 处理的全局错误
window.onerror = (message, source, lineno, colno, error) => {// 记录错误信息(如上报服务器)reportError({message, // 错误的描述 例如:"Uncaught TypeError: Cannot read properties of null (reading 'name')"source, // 发生错误的脚本文件 URLline: lineno, // 错误发生的行号column: colno, // 错误发生的列号stack: error?.stack // 实际的错误对象,包含完整的堆栈信息(stack属性)});// 返回 true 阻止默认事件(如控制台红色错误信息,某些浏览器有效,Chrome不支持)return true;
};
  • ② unhandledrejection:捕获未处理的 Promise 拒绝
window.addEventListener('unhandledrejection', event => {const error = event.reason;// 处理未被 .catch() 捕获的 Promise 错误console.error('未处理的 Promise 错误', error);event.preventDefault(); // 阻止控制台默认报错
});

4.框架层错误捕获

① React:通过 ErrorBoundary 组件捕获子组件错误

import { Component } from 'react';class ErrorBoundary extends Component {state = { hasError: false };componentDidCatch(error, info) {// 记录错误reportError(error, info); // 上报错误this.setState({ hasError: true });}render() {if (this.state.hasError) {// 显示错误提示return <div>页面出错啦,请刷新重试</div>;}return this.props.children;}
}

② Vue:通过 errorCaptured 钩子或全局 errorHandler

// 组件内捕获子组件错误
export default {errorCaptured(error, instance, info) {console.error('子组件错误', error, info);return false; // 阻止错误继续向上传播}
};// 全局捕获(main.js)
Vue.config.errorHandler = (error, vm, info) => {reportError(error, { vm, info });// 显示全局错误提示app.$message.error('系统异常,请稍后再试');
};

5.资源加载错误

捕获图片、脚本、样式等资源加载失败:

<img src="/invalid-image.jpg" onerror="this.src='default.jpg'; this.onerror=null" alt="默认图片"
><script src="/invalid.js" onerror="console.error('脚本加载失败')"
></script>

二、JS有多少种错误类型

1.ECMAScript标准错误

① 语法错误 SyntaxError:如缺少括号,关键字写错等
② 引用未定义变量 ReferenceError
③ 类型错误 TypeError:如对非函数的调用,属性不存在等
④ 超出范围错误 RangeError:数值长度超出范围,栈溢出

⑤ URI编码解码错误 URIError:decodeURI(‘%2’);
⑥ eval()执行错误 EvalError(逐渐废弃)

2.浏览器特定错误

① 网络请求失败 NetworkError:如 404、500 状态码
② DOM操作错误 DOMException:如删除非子节点
③ 安全策略阻止操作 SecurityError:如跨域访问

3.自定义错误

继承 Error 基类创建业务专属错误:

class NetworkError extends Error {constructor(message, statusCode) {super(message);this.statusCode = statusCode;this.name = 'NetworkError';}
}// 使用
try {if (res.status >= 400) {throw new NetworkError('请求失败', res.status);}
} catch (error) {if (error instanceof NetworkError) {showToast(`网络错误 ${error.statusCode}`);}
}

三、如何做统一的错误处理

1. 在项目中实现外层统一错误处理

需结合全局捕获、错误分类、日志上报,以及用户友好提示

  1. 通过window.onrror和监听unhandledrejection事件实现全局错误捕获
  2. 在用户提示层面,区分错误类型,返回不同提示
  3. 生产环境上,做错误日志上报

2.错误分级策略

  • 致命 Fatal(导致页面崩溃|核心功能不可用):立即报警,优先修复。例如白屏。
  • 错误 Error(影响部分功能,但页面可使用):24小时内修复。例如表单提交失败。
  • 警告 Warning(非阻塞性问题,可能引发潜在风险):版本迭代中优化。
  • 信息 Info(正常流程中的异常分支):定期分析,优化逻辑

3.监控能力

  • 错误捕获:运行时错误、资源加载错误、promise拒绝、异步错误
  • 上下文采集:用户环境(浏览器、系统、版本),影响范围(URL、路由记录),用户行为(点击、输入)
  • 错误分析:错误分组(按类型)、影响范围(受影响的用户、触发频率),趋势统计
  • 报警机制:邮件通知等

四、异常监控工具

- 常见的监控工具

Sentry:支持全平台监控、错误分组聚合、堆栈追踪、用户行为关联,生态丰富,适用中大型项目、复杂前端应用(免费版 + 企业付费版)
Bugsnag:轻量级、高可靠性,专注错误监控,提供详细的错误影响分析,适用对性能敏感的项目(免费版 + 付费版)
Fundebug:中文支持好,集成简单,提供可视化错误重现功能,适用中小型项目、快速接入需求(免费版 + 付费版)

- 以React为例,如何使用Sentry进行前端异常监控和处理

1.安装依赖

npm install @sentry/react @sentry/tracing

2.初始化(入口文件)
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';// 初始化 Sentry
Sentry.init({// 基础配置dsn: 'https://your-dsn@sentry.io/123456', // Sentry 项目的唯一标识符,类似于 API Keyintegrations: [new BrowserTracing({// 与 React Router 集成的核心逻辑,用于追踪路由变化routingInstrumentation: Sentry.reactRouterV6Instrumentation(React.useEffect, // React 生命周期钩子,监听路由变化的触发器useLocation, //获取当前 URL 路径useNavigationType, // 区分导航类型(如用户点击链接 vs 代码跳转)startTransaction // 创建 Sentry 性能事务)})],// 高级配置beforeSend: (event) => {// 错误发送前的回调函数,过滤特定错误if (event.message?.includes('Network request failed')) {return null; // 不上报网络请求失败}return event;// 过滤第三方脚本错误if (event.stacktrace && event.stacktrace.frames) {const isThirdParty = event.stacktrace.frames.some(frame => frame.filename && frame.filename.includes('node_modules'));if (isThirdParty) return null;}},attachStacktrace: true, // 强制附加堆栈信息,帮助定位错误发生的精确位置normalizeDepth: 5, // 堆栈追踪深度,避免深层嵌套对象导致的性能问题release: 'my-app@1.0.0', // 指定当前应用版本sampleRate: 0.8 // 错误采样率(控制错误上报量)tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.2 : 1.0, // 采样率(0-1),生产环境建议0.2environment: process.env.NODE_ENV // 区分开发/生产环境
});const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<React.StrictMode><App /></React.StrictMode>
);

<React.StrictMode>是开发阶段的问题检测工具,主要负责检查子树内组件的逻辑问题,仅在开发环境有效

3. 全局错误边界
// ErrorBoundary.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/react';class ErrorBoundary extends Component {state = { hasError: false };static getDerivedStateFromError() {return { hasError: true };}componentDidCatch(error, errorInfo) {// 上报错误到 SentrySentry.captureException(error, { extra: errorInfo });console.error('ErrorBoundary caught an error', error, errorInfo);}render() {if (this.state.hasError) {// 显示降级 UIreturn <div>页面加载失败,请刷新重试</div>;}return this.props.children;}
}export default ErrorBoundary;

ErrorBoundary是运行时的错误捕获机制,捕获其子树内的运行时错误,在开发 / 生产环境均生效,错误发生时会渲染备用 UI,防止组件错误导致页面崩溃,展示友好提示,仅捕获渲染同步错误,不捕获异步错误(setTimeout、Promise、fetch),所以需要下面的异步错误捕获

官方定义是:ErrorBoundary仅捕获渲染期间、生命周期方法和构造函数中的错误。但需要注意的是异步请求的响应处理错误,若在渲染时抛出则捕获,若在回调中抛出则不捕获

4.异步操作错误捕获
// 使用 useErrorBoundary 钩子捕获异步错误
import { useErrorBoundary } from '@sentry/react';function MyComponent() {const { showBoundary } = useErrorBoundary();const fetchData = async () => {try {const response = await fetch('/api/data');const data = await response.json();return data;} catch (error) {// 捕获异步错误并触发错误边界showBoundary(error);}};return <button onClick={fetchData}>加载数据</button>;
}
5. 路由追踪
// 增强路由错误监控
import {startTransaction,useLocation,useNavigationType,
} from '@sentry/react';
import {createRoutesFromElements,RouterProvider,useRoutes,
} from 'react-router-dom';// 包裹路由配置
const routes = createRoutesFromElements(<Route path="/" element={<App />}><Route path="dashboard" element={<Dashboard />} /><Route path="profile" element={<Profile />} /></Route>
);// 使用 Sentry 包装路由
const SentryRoutes = () => {const location = useLocation();const navigationType = useNavigationType();return useRoutes(routes, {onError(error) {Sentry.captureException(error);},beforeRouteRender() {startTransaction({name: 'Route Change',op: 'navigation',metadata: {source: 'route',route: location.pathname,},});},});
};// 在 RouterProvider 中使用
<RouterProvider router={{ routes: <SentryRoutes /> }} />
6. 自定义用户上下文
// 登录后设置用户信息,将错误与具体用户关联
Sentry.setUser({id: user.id,username: user.username,email: user.email
});// 登出时清除用户信息
Sentry.setUser(null);//  面包屑(Breadcrumbs)记录用户操作
Sentry.addBreadcrumb({category: 'ui.click',message: '用户点击提交按钮',data: { formFields: ['username', 'email'] },level: 'info'
});// 手动监控函数性能
const transaction = Sentry.startTransaction({name: 'fetchUserData',op: 'network'
});fetch('/api/user').then(res => res.json()).then(data => {transaction.finish(); // 结束事务}).catch(error => {transaction.setStatus('error');transaction.finish();Sentry.captureException(error);});

相关文章:

  • 模板方法模式Template Method Pattern
  • 移动应用开发实验室web组大一下期末考核题解
  • Vela sensor uORB 框架学习
  • 适配器模式Adapter Pattern
  • Java中如何使用lambda表达式分类groupby
  • STL容器分类总结
  • 探索RAGFlow:解锁生成式AI的无限潜能(2/6)
  • 第二十章 Centos8的使用
  • DP刷题练习(三)
  • linux thermal framework(4)_thermal governor
  • Linux 忘记root密码如何解决-linux025
  • 2.1 Windows VS2019编译FFmpeg 4.4.1
  • PCL 生成圆柱面点云
  • 人工智能-准确率(Precision)、召回率(Recall) 和 F1 分数
  • YOLO优化之双池化下采样融合块、注意力引导逆残差块
  • 第20篇:数据库中间件的热点 Key 缓存一致性策略与分布式协调机制
  • Spring Boot 整合 Swagger 快速生成 API 文档的最佳实践
  • Axure应用交互设计:中继器数据向多种类型元件赋值
  • jxWebUI--简单易用的webUI库
  • Iceberg与Hive集成深度
  • 三网合一网站 东莞/谷歌sem服务商
  • 德国购物网站大全/网站seo文章该怎么写
  • 小企业如何优化网站建设/seo基础教程
  • 青海网站开发建设/疫情最新资讯
  • 阿里云搭建网站/网络seo招聘
  • 有了虚拟主机怎么做网站/seo技术分享博客