查看: 77|回复: 1

Vue项目中全局错误监测与错误日志记录实现 - 涵盖JS/Vue/请求/Promise错误

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
上线后的Vue项目难免会出现各种运行时错误,如果不做全局监控,排查问题往往依赖用户反馈或测试重现。在项目中集成一套全局错误监测与日志记录机制,可以将常见的JS错误、静态资源加载失败、Vue渲染异常、请求错误以及Promise未捕获错误统一捕获,并存储到localStorage中。这样开发人员只要查看错误日志就能快速定位问题,大幅降低维护成本。

本文基于Vue3环境,完整实现一个命名为“watchError”的工具模块,包含错误码定义、错误处理函数、自动监听与落地方案。

一、准备工作
1. 错误码规定
使用Map定义一套自定义错误码,与请求状态码类似,便于区分错误类型:
  1. // 错误代码
  2. const errCode = new Map([
  3.   ['E1001', '系统未知错误'],
  4.   ['E1002', 'vue逻辑错误'],
  5.   ['E1003', 'JavaScript错误'],
  6.   ['E1004', '静态资源加载错误'],
  7.   ['E1005', '请求错误'],
  8.   ['E1006', 'Promise错误']
  9. ])
复制代码
2. 错误处理函数
export导出一个errorHandler函数,供后续手动调用(比如在Promise.catch或axios响应拦截器中)。该函数接收错误码、错误消息和可选的错误文件路径,内部调用来保存日志:
  1. export const errorHandler = (code: string, msg: string, file = 'null') => {
  2.   saveLog({
  3.     code: code,
  4.     type: errCode.get(`$[code]
  5. `),
  6.     msg: msg,
  7.     router: router.currentRoute.value.fullPath,
  8.     file: file,
  9.     createTime: new Date().toLocaleString()
  10.   })
  11. }
复制代码
3. 保存错误日志到localStorage
定义saveLog函数,将错误信息存入localStorage的“ERROR”字段,并限制最多保存50条,超出时替换最旧的一条。通过createTime排序保证后来者替换最早错误:
  1. type errorParams = {
  2.   code: string
  3.   msg: string
  4.   router: string
  5.   file?: string
  6.   createTime: string
  7.   type?: string
  8. }
  9. const saveLog = (data: errorParams): void => {
  10.   const nowData = localStorage.getItem('ERROR')
  11.   if (nowData) {
  12.     const allData = JSON.parse(nowData)
  13.     sortArray(allData)
  14.     if (allData.length > 50) {
  15.       allData[0] = data
  16.       sortArray(allData)
  17.     } else {
  18.       allData.push(data)
  19.     }
  20.     localStorage.setItem('ERROR', JSON.stringify(allData))
  21.   } else {
  22.     localStorage.setItem('ERROR', JSON.stringify([data]))
  23.   }
  24. }
  25. const sortArray = (allData: string[]) => {
  26.   allData.sort((a: any, b: any) => {
  27.     if (a.createTime > b.createTime) return 1
  28.     return -1
  29.   })
  30. }
复制代码
二、监听错误
项目上线后主要有四类错误需要捕获。利用Vue官方提供的app.config.errorHandler和window.addEventListener实现。
1. JS错误与静态资源加载错误
通过window的error事件统一监听,利用error.message是否存在来区分:
  1. window.addEventListener('error', (error: any) => {
  2.   if (error.message) {
  3.     // JS错误
  4.     console.error('监测到E1003错误');
  5.     errorHandler('E1003', error.message, error.filename)
  6.   } else {
  7.     // 静态资源加载错误
  8.     console.error('监测到E1004错误');
  9.     errorHandler('E1004', error.target.currentSrc, error.filename)
  10.   }
  11. }, true)
复制代码
注意:第三个参数为true,表示在捕获阶段监听,确保资源加载错误能被捕获。
2. Vue逻辑错误
利用app.config.errorHandler,它会在组件渲染、计算属性、侦听器等过程中捕获未处理的错误:
  1. app.config.errorHandler = (err: any) => {
  2.   console.error('监测到E1002错误');
  3.   errorHandler('E1002', err.name + ':' + err.message)
  4. }
复制代码
3. 请求错误与Promise错误
这两种错误需要开发者在使用时主动调用errorHandler,因为它们本身已有自己的错误处理机制。
- 请求错误:在axios响应拦截器中调用errorHandler,传入错误码E1005和错误详情。
- Promise错误:在catch块中调用errorHandler,传入错误码E1006。
  1. // 请求错误示例(在axios.interceptors.response内)
  2. errorHandler('E1005', `请求地址:${error.config.method}:${error.config.baseURL}/${error.config.url}`)
  3. // Promise错误示例
  4. errorHandler('E1006', '测试Promise错误')
复制代码
三、完整代码与使用方法
将上述逻辑整合到一个文件中,例如src/utils/watchError.ts。然后在main.ts中引入并启动:
  1. // main.ts
  2. import { createApp } from 'vue'
  3. import { createPinia } from 'pinia'
  4. import { watchError } from './utils/watchError'
  5. import App from './App.vue'
  6. import router from './router'
  7. const app = createApp(App)
  8. app.use(createPinia())
  9. app.use(router)
  10. app.mount('#app')
  11. watchError(app)
复制代码
watchError函数接收app实例,内部同时注册Vue错误处理器和全局error事件:
  1. export const watchError = (app: any) => {
  2.   app.config.errorHandler = (err: any) => {
  3.     console.error('监测到E1002错误');
  4.     errorHandler('E1002', err.name + ':' + err.message)
  5.   }
  6.   window.addEventListener('error', (error: any) => {
  7.     if (error.message) {
  8.       console.error('监测到E1003错误');
  9.       errorHandler('E1003', error.message, error.filename)
  10.     } else {
  11.       console.error('监测到E1004错误');
  12.       errorHandler('E1004', error.target.currentSrc, error.filename)
  13.     }
  14.   }, true)
  15. }
复制代码
使用时,对于axios请求错误和Promise.catch,手动引入errorHandler并调用。
错误日志会存储在localStorage的“ERROR”字段中,你可以开发一个管理页面(如表格)展示这些日志,方便线上排查。
四、总结
以上方案基于Vue3,通用性较强。通过自定义错误码、统一捕获策略与localStorage持久化,能够覆盖绝大多数线上运行时错误。实际项目中可根据需要扩展errorHandler逻辑,比如发送到服务器告警。需要注意的是,window.onerror和app.config.errorHandler都不能捕获所有异常(如异步代码内部未显式reject的情况),建议结合Promise错误手动处理。此方案已在个人项目中验证有效,可作为错误监控的基础模块。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Vue项目中全局错误监测与错误日志记录实现 - 涵盖JS/Vue/请求/Promise错误

非常感谢楼主分享这么完整的方案!我正好在给公司项目做全局错误监控,你这套体系覆盖了JS、Vue、请求和Promise四种核心错误类型,而且用自定义错误码和localStorage存储,感觉很实用。 有几个小细节想请教一下: 1. `saveLog` 里 `localStorage.setItem('ERROR', JSON.stringify())` 是不是笔误?应该是 `JSON.stringify()` 吧? 2. 用 localStorage 存储上限50条,如果用户页面长时间不关闭、报错较多,会不会丢日志?有没有考虑过同时上报到服务器(比如通过 `navigator.sendBeacon` 或异步请求)? 3. 对于 `Promise` 错误,是否建议在全局加一个 `unhandledrejection` 监听来兜底?这样即使开发者忘记写catch也能捕获到。 另外,分享一个我踩过的坑:Vue3 的 `app.config.errorHandler` 里如果本身抛出错误会导致死循环,建议用 `try...catch` 包一下。再次感谢,你的代码结构清晰,已经收藏了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-12 18:00 , Processed in 0.033358 second(s), 19 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部