pinia可通过插件+action拦截+状态管理实现可追踪、可开关、可上报、可本地暂存的错误日志收集;核心是定义errorlogstore管理enabled、queue等状态,并用$onaction和全局错误监听自动捕获异常。

Pinia 本身不内置错误日志收集功能,但可以通过插件机制 + 全局 action 拦截 + 状态管理三者协同,实现运行时全局错误日志的**可追踪、可开关、可上报、可本地暂存**的状态管理。核心思路是:把「错误日志收集开关」和「待上报错误队列」作为 store 的 state,再用 $onAction 和插件统一捕获源头,最后由业务逻辑或定时任务触发上报。
定义一个 errorLogStore 管理日志状态
创建独立 store 专注错误日志生命周期:
-
state:包含
enabled: boolean(是否开启收集)、queue: ErrorLogItem[](内存中暂存的错误项)、maxQueueSize: number(防爆仓) -
getters:如
hasErrors、errorCount,便于视图响应式判断 -
actions:提供
addError(err, context?)、clear()、flushToServer()、toggleEnabled()等方法
示例片段:
src/stores/useErrorLogStore.tsimport { defineStore } from 'pinia'
import { ref } from 'vue'
export interface ErrorLogItem {
id: string
message: string
stack?: string
url: string
timestamp: number
context?: Record<string any>
}
export const useErrorLogStore = defineStore('errorLog', () => {
const enabled = ref(true)
const queue = ref<errorlogitem>([])
const maxQueueSize = 50
function addError(err: Error, context: Record<string any> = {}) {
if (!enabled.value) return
const item: ErrorLogItem = {
id: Math.random().toString(36).substr(2, 9),
message: err.message,
stack: err.stack,
url: location.href,
timestamp: Date.now(),
context
}
queue.value.push(item)
if (queue.value.length > maxQueueSize) {
queue.value.shift()
}
}
function flushToServer() {
if (queue.value.length === 0) return
// 这里调用你的上报 API,例如:api.reportErrors(queue.value)
// 成功后清空队列
queue.value = []
}
return { enabled, queue, addError, flushToServer, clear: () => (queue.value = []) }
})</string></errorlogitem></string>
用 $onAction 全局拦截所有 store action 错误
在 store 初始化后,对所有 store 实例统一监听 action 执行失败,自动注入日志:
- 在
main.ts或 Pinia 插件中调用pinia.use() - 使用
onError钩子捕获 action 内抛出的错误 - 调用
useErrorLogStore().addError()记录,附带 action 名称和参数快照
这样,所有 store 中 async fetchUser()、submitForm() 等操作的异常都会被自动捕获并归集。
捕获全局未处理错误(window.onerror / unhandledrejection)
Pinia store 不负责监听浏览器级错误,需在应用入口手动绑定:
- 在
main.ts中注册window.addEventListener('error')和window.addEventListener('unhandledrejection') - 在回调中调用
useErrorLogStore().addError(),并标注来源为'global' - 注意过滤掉资源加载失败(
event.filename为空或为undefined时跳过)
按需启用/暂停收集,并支持手动触发上报
避免常驻收集影响性能,建议:
- 开发环境默认开启,生产环境默认关闭(或仅在用户授权后开启)
- 提供 UI 开关(如调试面板按钮),调用
store.toggleEnabled() - 关键路径(如支付、登录)可临时强制开启:
store.enabled = true - 支持离线缓存:错误队列可配合
pinia-plugin-unistorage持久化(仅存最近 10 条,避免敏感信息泄露)
上报时机可设为:页面卸载前(beforeunload)、队列满、定时 30 秒刷一次、或用户主动点击「提交日志」按钮。










