Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 819|回复: 0

nuxt.js项目中全局捕获异常并生成错误日志全过程

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-24 20:03:42 | 显示全部楼层 |阅读模式

     

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

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

      一.全局捕获异常

    如图,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});
    })

    最终成果如下:

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

    下面是日志的内容:

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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

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

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-22 19:13 , Processed in 0.066015 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表