前端Sentry的使用

0 阅读6分钟

一、前言

某天突然被@了一下

image.png

小小的思考了一下前端的错误捕获机制:

1、try...catch:局部/同步错误捕获

  • 捕获同步代码中抛出的错误
  • 异步情况下也可搭配await使用
  • 不会触发 window.onerror

2、window.onerror:全局同步错误兜底

window.onerror = function(message, source, lineno, colno, error) {
  console.log('全局捕获到错误:', error);
};
  • 捕获没有使用try...catch同步 JavaScript 错误
  • 资源错误的话不会触发,而是该资源元素自身的error事件

3、window.onunhandledrejection:Promise 未处理拒绝的兜底

window.addEventListener('unhandledrejection', event => {
  console.log('未处理的 Promise reject:', event.reason);
  event.preventDefault(); // 阻止浏览器打印警告(可选)
});
  • 捕捉一个Promise被reject(),且没有通过 .catch().then(null, ...)await + try...catch 进行处理
  • unhandledrejection 处理的是异步 Promise 的未处理 reject
  • 专为 Promise 设计

很明显,这些异常日志全都是报浏览器的控制台上的,看上去不太符合要求的样子,所以尝试用了市面比较流行的sentry

二、sentry基本信息

简介

  • Sentry 是一个 开源的、面向开发者的实时错误监控与性能追踪平台,主要用于前端、后端、移动端等应用的异常捕获、诊断和分析。它的核心目标是:让开发者更快地发现、定位并修复线上问题
  • 用户数据是红线,Sentry 会采集用户的 IP、设备信息、甚至操作行为,而Sentry是海外的sass服务,服务器自然也是海外的,所以更多情况下考虑私有化部署(sentry的运行配置要求挺高的)

作用和使用目的

  1. 自动捕获未处理的异常(js、vue、promise、nodejs、python、java、ios、android)
  2. 提供完整的错误上下文(用户浏览器/设备信息、操作系统、网络状态、用户id、页面Url和路由)
  3. 聚合重复错误,避免噪音(相同错误(相同堆栈 + 相同环境)会被自动归为 一个 Issue,显示发生次数、影响用户数、首次/最近发生时间)
  4. 性能监控(页面加载耗时(FCP, LCP)、API 接口响应时间、Vue/React 组件渲染性能)
  5. 关联发布版本Release(将错误与具体代码版本绑定(如 v1.2.3))
  6. 告警与协作(邮件、Slack、飞书、企业微信等通知)

三、前提条件

  • 一个vue项目,本文使用vue-cli脚手架创建的vue2项目tryAnyplugin(vue2 + webpack)
  • 注册Sentry账号(sentry.io/),可使用谷歌账号登录就可以

四、安装依赖

# 核心包
npm install @sentry/vue@6.19.7 @sentry/tracing@6.19.7# 如果是 Vue 2,还需要兼容包(可选)
npm install @sentry/integrations

💡 @sentry/tracing 用于性能监控(如页面加载、组件渲染耗时)

五、初始化 Sentry(在 main.js / main.ts 中)

import * as Sentry from '@sentry/vue'
import { Integrations } from '@sentry/tracing'
​
​
Sentry.init({
  Vue,
  dsn: 参数1(详情请查看下文,以下参数规则都是如此),
  integrations: [
    new Integrations.BrowserTracing(),
  ],
  tracesSampleRate: 1.0, // 建议配置0.2,开启性能监控,避免全量上报
  environment: process.env.NODE_ENV, // 环境标识
  release: '1.0.0',
  beforeSend(event, hint) { // 可配置一些已知错误(也可不配置)
    const error = hint.originalException
    if (error && error.message.includes('ResizeObserver')) {
      return null // 忽略 ResizeObserver 错误
    }
    return event
  }
})

六、配置 Webpack 插件(自动上传 Source Map)

现在的 Web 项目都是打包压缩过的,JS 代码混淆可能全是 a, b, c, d。为了在 Sentry 中看到 原始代码的错误位置(而非压缩后的 bundle.js),需要上传 Source Map。

步骤1:安装插件

npm install --save-dev @sentry/webpack-plugin@1.20.0

步骤2:在 vue.config.js 中配置(Vue CLI 项目)

const SentryWebpackPlugin = require('@sentry/webpack-plugin')
​
const isProd = process.env.NODE_ENV === 'production'module.exports = {
  configureWebpack: config => {
    if (isProd) {
      config.devtool = 'source-map' // 必须生成 source map,可以生成上传后删除map文件,避免上传到生产环境公网的服务器上
    }
  },
  chainWebpack: config => {
    console.log(isProd, 'isProd');
    if (isProd) {
      config.plugin('sentry').use(SentryWebpackPlugin, [{
        org: '参数2 Sentry 组织名',
        project: '参数3 项目名',
        authToken: '参数4 authToken',
        urlPrefix: '参数5 urlPrefix (~/dist) ', 
        include: './dist',  // 前端打包出来的相对目录地址
        ignore: ['node_modules', 'vue.config.js'], // 忽略
        release: '1.0.0', // 版本号,与main.js的配置的release应该保持一致,建议从package.json 读版本号
      }])
    }     
  }  
}
​

七、验证是否正确上传了Source Map

  • Settings → Projects → 选择对应的项目 → 在重新点击一下Settings → Processing下的Soure Maps
  • 查验是否上传.map格式的文件,有就是代表已成功上传了

image.png

八、验证是否能上报错误

步骤1:打包完成后,使用本地服务器访问(注意访问资源路径,看问题总结5),并手动触发错误

<template>
  <div>
    <button @click="noRegisterByClicking">没有注册点击事件</button>
  </div>
</template>
<script>
export default {
   mounted() {
    setTimeout(() => {
      throw new Error('Test Source Map in Sentry, Vue2 Webpack I am a test error');
    }, 2000);
  },
  methods: {
    noRegisterByClicking() {
      // 这里故意抛出一个错误以测试 Sentry 的错误捕获功能
      console.log(undefinedVariable);
    }
  }
}

步骤2:登录 Sentry 后台,查看 Issues 是否出现新错误

image.png

九、参数配置以及查询

参数1:dsn

  • Settings → Projects → 选择对应的项目 → 在重新点击一下Settings → SDK Setup下的Client Keys(DSN)
  • 复制DSN(格式如:https://xxxxxx@o123456.ingest.de.sentry.io/789012
  • 不要用 Secret DSN!前端只能用 Public DSN

🔒 安全提示:DSN 是公开的,不会泄露敏感信息,可明文放在main.js

参数2:Sentry 组织名

  • Settings → General Settings → Organization Slug

参数3:项目名

  • Settings → Projects → 复制对应的项目名称

参数4:authToken

  • Settings → Developer Settings → Personal Token → Create New Token

  • 需要勾选必要权限:

    • project:releases:必须,允许创建 release 和上传文件
    • project:write:必须,允许写入项目数据(包括 source maps)
    • org:read:推荐:读取组织信息
    • 不需要 adminmember:admin 等高危权限!
  • 创建后应立马复制,不可重新复制

🔒 安全提示:敏感信息,需要放在环境变量里(.env.test)

参数5:urlPrefix

  • Settings → projects → 对应的项目 → 在重新点击一下Settings → Processing下的Source maps

💡 这里要对应静态资源路径进行配置~/js/chunk-2d0e9b20.827fe60a.js.map

十、问题总结

1、开发环境下 能使用sentry吗

Sentry 本身不限制环境,只要:

  • 正确初始化
  • 提供有效的 DSN
  • 网络可访问 sentry.io

它就能上报错误,无论是在 localhost、测试服务器还是生产环境。

但是不建议开启,因为:

  • 开发时频繁报错,会污染Issues列表
  • 浪费配额,Sentry 免费版有事件数量限制(每月 5000 个事件)
  • 无实用价值,客户端的控制台就能查看

2、403 Forbidden

authToken 权限不足,检查创建一个token的时候有没有勾上对应的权限

3、Project not found

project 名称错误,检查 URL 中的项目 slug,vue.config.js里面的project

4、Organization not found

org 名称错误,检查 URL 中的组织 slug,vue.config.js里面的org

5、上传成功但 Sentry 看不到 source map

urlPrefix 不匹配,确保 urlPrefix 与线上 JS 路径一致(如 ~/static/js/)。(ps:使用时花在这里的时间最多)

例如:src="/static/js/chunk-vendors.abc123.js, 那么 urlPrefix 就是:~/static/js/

例如: 本地开发服务资源地址: http://127.0.0.1:5501/dist/js/chunk-11526b2f.de96035d.js, 打包出来index.html文件:href="js/chunk-2d0cfa3a.dce2e7f0.js",那么 urlPrefix 就是:~/dist/js/,与Sentry平台中对应,如下:

image.png

十一、后话

  1. 如果后续采用 Sentry,还得是私有化部署
  2. 本文仅当作本人文档记录,好记性不如烂笔头的意思