本文由云+社区发表

在前端,我们经常会通过 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 压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何?

堆栈查看工具

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

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

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

堆栈工具实现原理

一步步来说的话:

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

    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 随便画一画就好了。

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

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

如何优雅地查看 JS 错误堆栈?的更多相关文章

  1. 搭建前端监控系统(二)JS错误监控篇

    ===================================================================== 前端性能监控系统: DEMO地址    GIT代码仓库地址 ...

  2. 前端监控系列2 |聊聊 JS 错误监控那些事儿

    作者:彭莉,火山引擎 APM 研发工程师.2020年加入字节,负责前端监控 SDK 的开发维护.平台数据消费的探索和落地. 有必要针对 JS 错误做监控吗? 我们可以先假设不对 JS 错误做监控,试想 ...

  3. Webfunny知识分享:JS错误监控

    现在的前端开发已不再是刀耕火种的年代了,各种框架.编译工具层出不穷,前端监控系统也不甘其后,遍地开花. 前端正承受着越来越重的职责,前端的业务也变得越来越复杂,此时此刻我们就更需要一套完善的监控系统来 ...

  4. Fundebug上线Node.js错误监控啦

    作为全栈JavaScript错误实时监测平台,Fundebug的Node.js实时错误监测服务上线啦,我们能够帮助开发者及时,高效地发现并且解决Node.js错误,从而提高开发效率,并提升用户体验. ...

  5. React中如何优雅的捕捉事件错误

    React中如何优雅的捕捉事件错误 前话 人无完人,所以代码总会出错,出错并不可怕,关键是怎么处理. 我就想问问大家react的错误怎么捕捉呢? 这个时候: 小白:怎么处理? 小白+: ErrorBo ...

  6. 【win7下安装node.js错误:roling back action】与【"grunt" 不是内部或外部命令】 解决方法

    [win7下安装node.js错误:roling back action] 解决方法: Node.js 服务器端的JavaScript Node.js 是一个基于Chrome JavaScript 运 ...

  7. logger.error打印完整的错误堆栈信息

    使用Spring Boot项目中的日志打印功能的时候,发现调用Logger.errror()方法的时候不能完全地打印出网站的错误堆栈信息,只能打印出这个错误是一个什么错误. 为什么呢,原因在于这个方法 ...

  8. 利用Decorator和SourceMap优化JavaScript错误堆栈

    配合源码阅读体验更佳. 最近收到用户吐槽 @cloudbase/js-sdk(云开发Cloudbase的JavaScript SDK)的报错信息不够清晰,比如下面这条报错: 这属于业务型报错,对于熟悉 ...

  9. angular js 自定义js错误处理(Angularjs js error handler)

    使用AngularJS的时候,对JS错误如何自定义处理?(比如用Google Analytics记录angularjs使用中出现的js错误) AngularJS自带一个错误处理service:$exc ...

随机推荐

  1. [BZOJ1925][SDOI2010]地精部落(DP)

    题意 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N ...

  2. VB中StdPicture尺寸(Width,Height)转像素单位

    首先获得一个图片对象 Dim spic As StdPicture Set spic = LoadPicture("d:\0.bmp") '从文件获得 Set spic = Cli ...

  3. python中的矩阵、多维数组

    2. 创建一般的多维数组 import numpy as np a = np.array([1,2,3], dtype=int)  # 创建1*3维数组   array([1,2,3]) type(a ...

  4. ES6新增的常用数组方法(forEach,map,filter,every,some)

    ES6新增的常用数组方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍历数组 arr.forEach((v, i) => { console.log( ...

  5. PHP实现微信模板消息发送给指定用户

    使用公众号的模板消息功能,必须是认证过的服务号,需要发送微信号的openid,同一微信号在不同公众号下的openid是不同的,在公众号下是唯一的,获取不到微信号 进入公众平台  功能->模板消息 ...

  6. apicloud实现各种自定义弹层组件

  7. C#嵌套类

    { "children" : [{ "children" : [{ "children" : [], "name" : ...

  8. Docker的基本概念

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...

  9. charles-web端开发者实用功能点

    ##网速模拟功能 throttle功能对于前端来说非常实用,可以看页面在低网速下的表现,从而找出优化的点. 在线上环境通常有些因为网速慢导致的bug,在本机无法重现,那时候就很抓瞎,如果嫌远程麻烦,推 ...

  10. FluentDataflow - Fluent Style TPL Dataflow

    我的新英文博客文章: FluentDataflow - Fluent Style TPL Dataflow 介绍了本人最新发布的一个开源类库:FluentDataflow--Fluent风格的TPL ...