需求:客户在使用过程中页面报错时,可以生成错误记录传回服务器,以便改进。

  步骤:
    一.全局捕获异常,
    二.发送到服务端,
    三.生成错误日志。

  一.全局捕获异常

如图,vue提供了errorHandle这个方法来处理全局异常,更多详细内容参见官网

我在页面中写了一个错误的函数,触发了errorHandler,控制台打印如下:

在utils.js中写了如下代码:

1 //系统错误捕获
2 const errorHandler = (error,vm,info)=>{
3 getErr(error,vm,info);
4 }
5
6 Vue.config.errorHandler = errorHandler;
7 Vue.prototype.$throw = (error,vm,info)=> errorHandler(error,vm,info);

然后在另一个公用的js(commonService.js)中:

/**
* 捕获异常
*/ const getErr = async(err,_this,info) => {
_this.$store.dispatch('getErr',{
err:err.stack,
hook:info
}
}

说明一下,之所以写在两个文件中,是因为项目结构就是这样的。

  二.发送到服务端

  接下来就是如何把请求发送到node服务器上了。既然通过dispatch触发,那就统一在store目录下的index.js中处理:

// 捕获异常,存在node服务器中
async getErr({ commit },{ err_info }) {
console.log({err_info})
await axios.post('/api/getErr',{ err_info })
}

在浏览器中调试,发现接口报了500.发现err_info是undefined,即{err_info}是{"err_info":undefined}。找了半天也没发现问题,所以就不再通过dispatch触发,直接在commonService.js中拿到数据就发到node服务器。另外,查资料的时候看到dispatch中最多只能传两个参数,还有一个是commit,所有可以把其他的参数拼装在一个对象中,避免出现undefined。这条没有实践过,暂时存疑。于是我在commonService.js中修改了原来的代码,结果如下:

const getErr = async(err,_this,info) => {
await axios.post('/api/getErr',{ err:err.stack,hook:info })
}

运行一下,请求发送成功,如图:

  三.生成错误日志

  OK,现在服务端已经收到请求,但是还没有返回值,所以要开始写服务端的代码了。我们的项目是基于nuxt的,所以代码在api/index.js中:

// 捕获异常
router.post('/getErr', (req, res) => {
req.session.getErr = {err:req.body.err,hook:req.body.hook};
return res.json({ok: true})
})

终于在network中看到返回值了...接下来就要生成错误日志并保存到服务器了。照例开始查文档:http://nodejs.cn/api/fs.html。首先要引入文件系统(File System,就是下文的fs):

const fs = require('fs');

写文件的方法是writeFile,异步地写入数据到文件,如果文件已经存在,则覆盖文件。

fs.writeFile(file, data[, options], callback)

具体参数如下:

文件名加上时间戳,每次都生成一个新文件,点点点点,于是有了好多日志文件:

贴一下代码:

// 捕获异常
router.post('/getErr', (req, res) => {
req.session.getErr = {err:req.body.err,hook:req.body.hook,userInfo:req.body.userInfo};
let time = new Date();
// 记录错误内容
fs.writeFile(
'tm_wap_err_' + time.getTime() +'.txt',
'报错内容:' + req.session.getErr.err + '\r\n' +
'所在钩子:' + req.session.getErr.hook + '\r\n' +
'报错时间:' + time.toLocaleString() + '\r\n' +
'用户信息:' + JSON.stringify(req.session.getErr.userInfo),
(err) => {
if (err) throw err;
});
// console.log(666,req.session.getErr);
return res.json({ok: true});
})

这里我还记录了时间用户的登录状态。需求大体完成了,想办法优化一下,每次报错都生成一个新文件感觉太奢侈了,能不能搞个增量更新,统一记录在一个文件中?既方便查阅又省空间,还能练手,那就搞起来吧!大致思路如下:先判断文件是否存在,若不存在就创建一个。读取到文件内容以后再新加上跟新的内容,然后再写入。这种方式涉及到了I/O操作,但是相比增加很多文件还是会性能更好吧。最终代码如下:

// 捕获异常
router.post('/getErr', (req, res) => {
req.session.getErr = {
err:req.body.err,
hook:req.body.hook,
userInfo:req.body.userInfo,
url:req.body.url
};
let time = new Date();
let content = '';
// 若文件不存在,就创建一个吧!
fs.exists("toolmall_wap_err.txt", function(exists) {
if(!exists) {
fs.writeFile('toolmall_wap_err.txt','', function(err) {
if(err) {
return console.log(err);
}
});
}
}); // 增量更新日志文件,先读取
fs.readFile('toolmall_wap_err.txt','utf8',(err, data) => {
if (err) throw err;
data += '\r\n';
data += '报错内容:' + req.session.getErr.err + '\r\n';
data += '所在钩子:' + req.session.getErr.hook + '\r\n';
data += '报错时间:' + time.toLocaleString() + '\r\n';
data += '报错页面:' + req.session.getErr.url + '\r\n';
data += '用户信息:' + JSON.stringify(req.session.getErr.userInfo) + '\r\n';
content = data;
// 记录错误内容
fs.writeFile(
'toolmall_wap_err.txt',
content,
(err) => {
if (err) throw err;
});
});
return res.json({ok: true});
})

最终成果如下:

以上是文件夹,放在了根目录下。

下面是日志的内容:

  终于完成了,今晚加鸡腿~

nuxt.js项目中全局捕获异常并生成错误日志全过程的更多相关文章

  1. Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验

    vee-validate 是为 Vue.js 量身打造的表单校验框架,允许您校验输入的内容并显示对应的错误提示信息.它内置了很多常见的校验规则,可以组合使用多种校验规则,大部分场景只需要配置就能实现开 ...

  2. Nuxt.js项目实战

    感悟 经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是我们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方还是很给力的,提issue后很积极的给 ...

  3. 如何Vue-cli开始使用在Vue.js项目中启动TDD(测试驱动开发)

    通常,使用测试驱动开发(TDD)最困难的部分是开始.你必须下载带有奇怪依赖项的软件包,让测试套件与你的构建系统协同工作,然后你必须弄清楚如何编写一个测试!难怪这么多的开发者在你提起它的时候就开始跑开了 ...

  4. vue项目中全局配置变量

    在项目中api管理需要用到全局变量,创建全局变量的方式也有很多. 1.通过export default const BASEURL = "http://localhost:3333/&quo ...

  5. 在项目中全局添加FastClick导致图片上传插件在ios端失效的解决方案

    ---恢复内容开始--- 项目是移动端的项目,为了解决300ms的click延迟,所以在全局中加入了FastClick,引入的方式很简单,网上一大堆教程,这里不做赘述 我们就谈,我遇到的问题: 某天产 ...

  6. Vue main.js 文件中全局组件注册部分

    在 \src\components\index.js 文件中export组件 import HeaderList from './HeaderList' import HeaderMenu from ...

  7. 前端技术之:使用npx创建一个Nuxt.js项目

    $ npx create-nuxt-app my-first-nuxtjs npx: 401 安装成功,用时 43.891 秒 > Generating Nuxt.js project in / ...

  8. Vue.js项目中使用iconfont冲突问题解决

    在开发前端项目中,字体图标变得越来越常用.一方面因为它比图片使用起来方便,可以像字体一样修改大小和颜色:另一方面是因为它可以减少请求数量,优化前端性能. iconfont的使用方法很简单,主要由三种引 ...

  9. 1000多个项目中的十大JavaScript错误以及如何避免

    通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个.下面会向大家介绍这些错误发生的原因以及如何防止. 对于这些错误发生的次数,我们是通过收集的数据统计得出的 ...

  10. Database项目中关于Procedure sp_refreshsqlmodule_internal的错误

    最近项目中发现一怪问题,使用DB项目发布数据库时,总提示 “(110,1): SQL72014: .Net SqlClient Data Provider: Msg 1222, Level 16, S ...

随机推荐

  1. jenkins启动失败,查看状态提示active(exited)

    chown -R jenkins:jenkins /var/lib/jenkins chown -R jenkins:jenkins /var/cache/jenkins chown -R jenki ...

  2. arcengine动态显示所需字段值

    需求:实现和GIS桌面端中Identify的类似功能,鼠标滑动的时候可以显示鼠标所在位置的要素的指定字段的值.. 主要操作流程: ①先打开一个对话框,用于选择需要显示的图层和字段名 ②点击确定之后,在 ...

  3. jvm垃圾收集器汇总

    1.吞吐量和延时 吞吐量:吞吐量指的是cpu的利用时间,计算公式是 运行用户代码时间  / (用户代码时间 + 垃圾收集时间),吞吐量越大说明cpu的利用率越大. 延时:延时指的是停顿时间,用户代码不 ...

  4. 自定义DOM事件函数封装

    非原生DOM触发,个性化定制的自定义事件. currentTarget(DOM对象):要触发事件的元素节点. type(字符串):触发的事件类型,例如"keydown". bubb ...

  5. SpringBoot使用OkHttp

    参考文章: https://www.cnblogs.com/hongdada/p/9259965.html https://blog.csdn.net/qq_41890954/article/deta ...

  6. 为什么要用Redis压缩表,是快吗?

    首先需要了解什么是压缩表,推荐Redis设计与实现第二版:压缩列表_w3cschool 为什么要用压缩表呢?是快吗? 其实不是的,恰恰相反,ziplist 是为了节省内存而设计出来的一种数据结构.zi ...

  7. springboot 连接不上 redis 的三种解决方案!

    针对于这种情况,首先,我们最简单直接的方法就是需要确认Redis是否已经正常启动(验证方法:如果安装在Linux下的话可以使用ps-ef|grep redis来进行确认是否开启) 如果未开启,我们可以 ...

  8. ByteHouse:基于 ClickHouse 的实时计算能力升级

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 ByteHouse 是火山引擎数智平台旗下云原生数据分析平台,为用户带来极速分析体验,能够支撑实时数据分析和海量离 ...

  9. 剑指 offer 第 4 天

    第 4 天 查找算法(简单) 剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但 ...

  10. vue中使用西瓜视频中引入自定义样式,绝对可以

    首先配置sass-loader和raw-loader 方法,再vue-config.js中加上这一段代码 module.exports = { chainWebpack: config => { ...