当前位置: 首页 > news >正文

如何优雅地查看 JS 错误堆栈?

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

本文由云+社区发表

在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个:

TypeError: Cannot read property 'module' of undefined
    at Object.exec (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:16:29828)
    at HTMLLIElement.<anonymous> (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:25:6409)
    at HTMLDivElement.dispatch (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:248887)
    at HTMLDivElement.y.handle (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:245631)

这个堆栈,你看得出问题来吗?我们发布到 CDN 的脚本文件,普遍是经过 UglifyJS 压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何?

img堆栈查看工具

眼尖的同学,一眼就能找到问题。这里的 p[e] 出现了可能为 undefined 的情况。

这样一个工具,大大提高了问题定位的效率。

好,这里不卖瓜,我们来看下这当中的实现原理。

img堆栈工具实现原理

一步步来说的话:

  • 拿到原始堆栈字符串,使用

    error-stack-parser

    解析为堆栈帧,每个堆栈帧包含三个最重要的字段:

    • url - 源码的 URL 地址
    • line - 堆栈位置行号
    • col - 堆栈位置列号
  • 对于 url,我们可以用于加载源码内容,得到 source

  • source 使用 UglifyJs 反向美化成多行的代码 prettysource,并且同时生成 sourcemap

  • 堆栈帧中的 linecol 通过 sourcemap 反查,得到美化后对应的 prettylineprettycol

  • prettysourceprettylineprettycol 给到 Monaco Editor 渲染,就可以得到上述截图的效果

说那么多,不如贴代码是吧:

var result = UglifyJS.minify(source, {
  output: {
    beautify: true
  },
  sourceMap: {
    filename: 'pretty.js',
    url: 'pretty.js.map'
  }
});
var code = result.code;
var rawSourceMap = JSON.parse(result.map);
var consumerPromise = new sourceMap.SourceMapConsumer(rawSourceMap);

resolve(
  consumerPromise.then(function(consumer) {
    return {
      code: code,
      sourceMapConsumer: consumer
    }
  })
);

上面就是使用 UglifyJs 对压缩代码进行反向美化的核心代码。下面给出 SourceMap 的使用源码:

var code = result.code;
var consumer = result.sourceMapConsumer;

var position = consumer.generatedPositionFor({
  source: '0',
  line: lineNumber,
  column: columnNumber
});

parent.postMessage({
  event: 'js-prettify-callback',
  payload: {
    hash: payload.hash,
    result: 'success',
    prettySource: code,
    prettyLineNumber: position.line,
    prettyColumnNumber: position.column + 1
  }
}, sourceOrigin);

完整源码有兴趣的读者也可以下下来把玩把玩:

js-loader.html.zip

源码只包含堆栈解析的实现,UI 的实现不在本文的讨论之内,用 React 随便画一画就好了。

此文已由作者授权腾讯云+社区在各渠道发布

获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号

转载于:https://my.oschina.net/qcloudcommunity/blog/3001634

相关文章:

  • [转]IPTABLES中SNAT和MASQUERADE的区别
  • PaddlePaddle-GitHub的正确打开姿势
  • Codeforces 1097 Alex and a TV Show
  • 第八届(2018)CSR年度盛典在北京举办
  • 身残心不残 河北大城63岁独身老人捐献遗体
  • Spring Batch JSON 支持
  • settings配置数据库和日志
  • K-means 怎么选 K ?
  • 蚂蚁金服庆涛:OceanBase支撑2135亿成交额背后的技术原理
  • Electron构建跨平台应用Mac/Windows/Linux
  • 每个 JavaScript 开发者都该了解的 ES2018 新特性
  • 混合式开发框架资料汇总
  • Python爬虫初学者需要了解的知识与技能
  • js获取客户端本地ip
  • 「小程序JAVA实战」小程序视频播放的时候生命周期的控制(56)
  • [Vue CLI 3] 配置解析之 css.extract
  • create-react-app做的留言板
  • express + mock 让前后台并行开发
  • javascript数组去重/查找/插入/删除
  • js面向对象
  • Python中eval与exec的使用及区别
  • spark本地环境的搭建到运行第一个spark程序
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • spring学习第二天
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 缓存与缓冲
  • 前端路由实现-history
  • 区块链分支循环
  • 设计模式走一遍---观察者模式
  • 问题之ssh中Host key verification failed的解决
  • 我的zsh配置, 2019最新方案
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 再次简单明了总结flex布局,一看就懂...
  • 走向全栈之MongoDB的使用
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 阿里云API、SDK和CLI应用实践方案
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # C++之functional库用法整理
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #pragma data_seg 共享数据区(转)
  • #Z0458. 树的中心2
  • (2)STM32单片机上位机
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (Java)【深基9.例1】选举学生会
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (六)激光线扫描-三维重建
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (小白学Java)Java简介和基本配置
  • (学习日记)2024.01.09
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转载)Linux网络编程入门
  • ******IT公司面试题汇总+优秀技术博客汇总