Vue全局监测错误生成错误日志过程
Vue项目通过window.addEventListener和app.config.errorHandler全面捕获JS错误、静态资源加载失败(如图片、CSS)及Vue组件内部逻辑异常,同时结合错误码映射、axios拦截器与Promise.catch统一处理网络请求与Promise异步错误,将错误日志存入localStorage并限制最多保存50条,自动覆盖
前言
项目交付之后,真正的考验才刚开始——后期维护的难度,往往直接决定了这个项目能走多远。如果能提前配置一套错误日志记录机制,维护工作会轻松不少。虽然未必能捕获所有异常,但绝大多数常见错误都能被实时监测到。这样一来,测试人员也无需反复手动复现bug,效率提升相当明显。
一、准备工作
(1)规定错误码
就像HTTP状态码(404、500)一样,每个错误都应该有对应的编码,方便快速定位和分类。以下是一个简单的错误码映射示例:
// 错误代码 const errCode = new Map([ // 本地系统错误 ['E1001', '系统未知错误'], ['E1002', 'vue逻辑错误'], ['E1003', 'Ja vaScript错误'], ['E1004', '静态资源加载错误'], ['E1005', '请求错误'], ['E1006', 'Promise错误'] ])
(2)设置错误处理函数
不同项目对错误的处理逻辑各有差异,这里只做最基础的日志保存操作。导出的errorHandler函数可以手动调用,用于处理请求错误和Promise.catch()中的异常。
// 错误处理函数
export const errorHandler = (code: string, msg: string, file = 'null') => {
// 这里处理监听到的错误
// 保存错误信息
sa veLog({
code: code,
type: errCode.get(`$[code]`),
msg: msg,
router: router.currentRoute.value.fullPath,
file: file,
createTime: new Date().toLocaleString()
})
}
(3)保存错误日志
演示中我们将日志存入localStorage,最多保留50条,超过时自动删除最旧的那条。
type errorParams = {
code: string // 错误代码
msg: string // 错误内容
router: string// 错误路由地址
file?: string// 错误的文件(不一定有)
createTime: string// 发现错误的时间
type?: string// 错误的类型
}
// localstorage 保存错误信息 最多50条避免爆满
const sa veLog = (data: errorParams): void => {
const nowData = localStorage.getItem('ERROR')
if (nowData) {
const allData = JSON.parse(nowData)
sortArray(allData)
// 只存50条错误信息
if (allData.length > 50) {
// 已存50条
allData[0] = data
sortArray(allData)
} else {
allData.push(data)
}
localStorage.setItem('ERROR', JSON.stringify(allData))
} else {
localStorage.setItem('ERROR', JSON.stringify([data]))
}
}
二、监听错误
项目上线后常见的错误类型主要有四种:JS错误、静态资源加载错误、Vue逻辑错误和请求错误。其他类型的错误一般在开发阶段就已经暴露了,所以重点监控这四类基本就能覆盖线上大部分异常场景。
(1)JS错误与静态资源加载错误
比如访问数组或对象中不存在的属性,都属于这一类。通过以下方式可以统一监听:
window.addEventListener('error', (error: any) => {
// 区分是否是js错误
if (error.message) {
console.error('监测到E1003错误');
errorHandler('E1003', error.message, error.filename)
} else {
console.error('监测到E1004错误');
errorHandler('E1004', error.target.currentSrc, error.filename)
}
}, true)
(2)Vue逻辑错误
Vue官方提供了全局错误捕获钩子 app.config.errorHandler,可以在组件渲染或侦听器执行期间捕捉未处理的异常。在main.ts中注册即可:
// vue渲染或者vue处理错误
app.config.errorHandler = (err: any) => {
console.error('监测到E1002错误');
console.error(err);
errorHandler('E1002', err.name + ':' + err.message)
}
(3)请求错误与Promise错误
这两种错误本身有独立的捕获机制。请求错误可以在axios响应拦截器(axios.interceptors.response)中统一处理;Promise错误则直接在catch中调用errorHandler即可。代码不再赘述。
三、效果演示
简单做了一个表格来展示日志记录的效果:

四、完整代码
使用方式:在main.ts中引入并调用watchError函数:
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { watchError } from './utils/watchError'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
// 如果没有app,自己用个变量等于createApp即可
watchError(app)
手动调用:Promise.catch()与请求拦截器中直接使用errorHandler:
import { errorHandler } from '../utils/watchError'
errorHandler('E1006', '测试Promise错误')
errorHandler('E1005', `请求地址:${error.config.method}:${error.config.baseURL}/${error.config.url}`)
监听函数(完整文件 src/utils/watchError.ts):
// src/utils/watchError.ts
import router from '@/router/index'
// 错误代码
const errCode = new Map([
// 本地系统错误
['E1001', '系统未知错误'],
['E1002', 'vue逻辑错误'],
['E1003', 'Ja vaScript错误'],
['E1004', '静态资源加载错误'],
['E1005', '请求错误'],
['E1006', 'Promise错误']
])
// 开启监听
export const watchError = (app: any) => {
// vue渲染或者vue处理错误
app.config.errorHandler = (err: any) => {
console.error('监测到E1002错误');
console.error(err.filename);
errorHandler('E1002', err.name + ':' + err.message)
}
// 静态资源加载错误 或者 JS错误
window.addEventListener('error', (error: any) => {
// 区分是否是js错误
if (error.message) {
console.error('监测到E1003错误');
errorHandler('E1003', error.message, error.filename)
} else {
console.error('监测到E1004错误');
errorHandler('E1004', error.target.currentSrc, error.filename)
}
}, true)
}
// 错误处理函数
export const errorHandler = (code: string, msg: string, file = 'null') => {
// 这里处理监听到的错误
// 保存错误信息
sa veLog({
code: code,
type: errCode.get(`$[code]`),
msg: msg,
router: router.currentRoute.value.fullPath,
file: file,
createTime: new Date().toLocaleString()
})
}
type errorParams = {
code: string // 错误代码
msg: string // 错误内容
router: string// 错误路由地址(根据hash地址‘/#/'切割而来,具体看需求)
file?: string// 错误的文件(不一定有)
createTime: string// 发现错误的时间
type?: string// 错误的类型
}
// localstorage 保存错误信息 最多50条避免爆满
const sa veLog = (data: errorParams): void => {
const nowData = localStorage.getItem('ERROR')
if (nowData) {
const allData = JSON.parse(nowData)
sortArray(allData)
// 只存50条错误信息
if (allData.length > 50) {
// 已存50条
allData[0] = data
sortArray(allData)
} else {
allData.push(data)
}
localStorage.setItem('ERROR', JSON.stringify(allData))
} else {
localStorage.setItem('ERROR', JSON.stringify([data]))
}
}
// 错误日志排序
const sortArray = (allData: string[]) => {
allData.sort((a: any, b: any) => {
if (a.createTime > b.createTime) {
return 1
}
return -1
})
}
五、总结
这套方案主要基于项目实际需求设计,如果希望获取更丰富的错误信息(比如调用栈、用户操作路径等),可以直接从error对象中进一步提取。以上思路与代码来自实际项目实践,希望能为遇到类似需求的朋友提供一些参考。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















