在前端项目中,如果能比用户更早发现代码异常,就可以在问题扩散前修复。实现这一目标需要两步:捕获运行时错误,并将错误信息上报到开发者手中。下面以 Vue3 为例,介绍如何结合全局错误处理器和邮件发送服务搭建一套简易的错误监控方案。
## 一、Vue3 全局错误捕获
Vue3 提供了 app.config.errorHandler 钩子,可以捕获组件渲染、侦听器执行期间未处理的错误。在 main.ts 中注册:
- import { createApp } from 'vue'
- import App from './App.vue'
- const app = createApp(App)
- app.config.errorHandler = (err, vm, info) => {
- console.log('[全局异常]', err, vm, info)
- }
- app.mount('#app')
复制代码
当代码中发生未捕获异常时(例如访问未定义的变量),控制台会输出类似以下信息:
- [全局异常] ReferenceError: www is not defined
- at asset-mgmt.vue:241:15
- at callWithErrorHandling (runtime-core.esm-bundler.js:155:22)
- ...
复制代码
这样就完成了错误采集的第一步。
## 二、错误信息上报:邮件方案
捕获到错误后,需要将信息发送出去。常见方式包括通过后端邮件接口发送,或由前端直接调用邮件服务。这里重点介绍第二种——用 Node.js 模块 Nodemailer 独立实现邮件发送,从而不依赖后端团队。
### 2.1 Nodemailer 服务端脚本
Nodemailer 是一个 Node.js 邮件发送库,支持 SMTP、Sendmail 等方式。注意:它运行在 Node 环境,不能在浏览器中直接使用。因此需要单独启动一个 Node 服务,接收前端上报的错误,并转发邮件。
以下是一个完整的测试脚本,使用 QQ 邮箱的 SMTP 服务发送邮件:
- 'use strict';
- const nodemailer = require('nodemailer');
- nodemailer.createTestAccount((err, account) => {
- if (err) {
- console.error('Failed to create a testing account', err);
- process.exit(1);
- }
- // 创建传输对象
- let transporter = nodemailer.createTransport(
- {
- host: "smtp.qq.com",
- port: 465,
- secure: true, // true for 465, false for other ports
- auth: {
- user: "your_email@qq.com", // 发送方邮箱
- pass: "your_authorization_code" // QQ邮箱授权码
- },
- logger: true,
- transactionLog: true
- },
- {
- from: 'Nodemailer <your_email@qq.com>',
- headers: {
- 'X-Laziness-level': 1000
- }
- }
- );
- // 邮件内容
- let message = {
- to: 'receiver@qq.com',
- subject: 'Frontend Error Report - ' + Date.now(),
- text: 'Error details will be placed here',
- html: '',
- attachments: []
- };
- transporter.sendMail(message, (error, info) => {
- if (error) {
- console.log('Error occurred', error.message);
- process.exit(1);
- }
- console.log('Message sent successfully!');
- console.log(nodemailer.getTestMessageUrl(info));
- transporter.close();
- });
- });
复制代码
运行此脚本前需确保:
- 发送方与接收方邮箱相同(即自己给自己发)
- QQ邮箱需开启 SMTP 服务并生成授权码
- 使用 node 命令启动脚本,而非在浏览器中直接调用
### 2.2 与 Vue3 errorHandler 集成
实际使用时,将上述 Node 脚本改造为 HTTP 服务(例如使用 Express),并在 Vue 的 errorHandler 中通过 AJAX 请求将错误信息发往该服务,再由服务端调用 nodemailer 发送邮件。
## 三、替代方案:Formspree
如果不想维护 Node 服务,可以使用 Formspree 这类表单转发服务。操作步骤如下:
1. 注册并登录 Formspree
2. 配置接收邮箱并验证
3. 创建一个 form,获取 endpoint 地址(例如 https://formspree.io/f/xvolyepj )
4. 在 Vue 的 errorHandler 中向该地址 POST 错误信息:
- app.config.errorHandler = (err, vm, info) => {
- axios({
- method: 'post',
- url: 'https://formspree.io/f/xvolyepj',
- data: {
- errorMsg: err.message,
- errorDetail: err.stack
- }
- })
- }
复制代码
注意:Formspree 免费版每月限制 50 条,超出后需要付费。此外,该方式依赖外网环境,内网项目无法使用。
## 四、总结
通过 Vue3 的 app.config.errorHandler 可以轻松捕获全局异常。上报方式可根据项目条件选择:如果能部署 Node 服务,使用 Nodemailer 发送邮件更可控;若项目简单且接受每月 50 条限制,Formspree 是快速选项。两种方案都无法在内网使用,若完全内网环境需自建邮件发送接口。 |