如何優雅地檢視 JS 錯誤堆疊?
本文由雲+社群發表
在前端,我們經常會通過 window.onerror
事件來捕獲未處理的異常。假設捕獲了一個異常,上報的堆疊是這個:
TypeError: Cannot read property 'module' of undefined
at Object.exec (https://my.cdn.com/dest/app.ef ... :29828)
at HTMLLIElement.<anonymous> (https://my.cdn.com/dest/app.ef ... 5:6409)
at HTMLDivElement.dispatch (https://my.cdn.com/dest/vendor ... 248887)
at HTMLDivElement.y.handle (https://my.cdn.com/dest/vendor ... 245631)
這個堆疊,你看得出問題來嗎?我們釋出到 CDN 的指令碼檔案,普遍是經過 UglifyJS 壓縮的,所以堆疊可讀性相當的差。假如有下面的一個堆疊檢視工具,又如何?
堆疊檢視工具
眼尖的同學,一眼就能找到問題。這裡的 p[e]
出現了可能為 undefined
的情況。
這樣一個工具,大大提高了問題定位的效率。
好,這裡不賣瓜,我們來看下這當中的實現原理。
堆疊工具實現原理
一步步來說的話:
-
拿到原始堆疊字串,使用
error-stack-parser
解析為堆疊幀,每個堆疊幀包含三個最重要的欄位:
url
- 原始碼的 URL 地址line
- 堆疊位置行號col
- 堆疊位置列號
-
對於
url
,我們可以用於載入原始碼內容,得到source
-
source 使用 UglifyJs 反向美化成多行的程式碼
prettysource
,並且同時生成sourcemap
-
堆疊幀中的
line
和col
通過sourcemap
反查,得到美化後對應的prettyline
和prettycol
- 將
prettysource
、prettyline
、prettycol
給到 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);
完整原始碼有興趣的讀者也可以下下來把玩把玩:
原始碼只包含堆疊解析的實現,UI 的實現不在本文的討論之內,用 React 隨便畫一畫就好了。
此文已由作者授權騰訊雲+社群在各渠道釋出
獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社群-雲加社群官方號及知乎機構號
相關文章
- 利用Decorator和SourceMap優化JavaScript錯誤堆疊優化JavaScript
- StackOverflowError堆疊溢位錯誤Error
- JS 堆疊JS
- pretty-printers:更優雅的看GDB堆疊資訊
- Go 錯誤堆疊資訊之 CockroachDB errors 庫GoError
- 【原創】mysql 錯誤緩衝堆疊薦MySql
- 通過錯誤堆疊資訊和原始碼分析錯誤來源原始碼
- 如何優雅地使用 macOSMac
- 如何優雅地使用 GitGit
- 深入理解 JavaScript 錯誤和堆疊追蹤JavaScript
- 使用Error Stack跟蹤Oracle錯誤堆疊資訊ErrorOracle
- 如何優雅的在 koa 中處理錯誤
- 優雅地除錯線上程式碼除錯
- Git | 如何優♂雅地管理版本Git
- 如何優雅地黑C++?C++
- JavaScript 錯誤處理和堆疊追蹤淺析JavaScript
- 嘗試寫個UC瀏覽器(堆疊檢視A)瀏覽器
- [JVM工具(1)] 堆疊檢查利器jstat的使用JVMJS
- 如何優雅地取消Retrofit請求?
- Swift:如何優雅地使用 print()(三)Swift
- 如何優雅地提取 App 的素材APP
- 圖的深度優先遍歷[非堆疊、堆疊實現]
- thinkphp console 命令列列印錯誤呼叫堆疊PHP命令列
- 如何優雅的在Golang中進行錯誤處理Golang
- 如何使用 RxJS 更優雅地進行定時請求JS
- 輕巧的執行緒堆疊檢視工具HotThreads執行緒thread
- Laravel/Lumen 自定義錯誤日誌格式過濾堆疊資訊Laravel
- 如何優雅地列印一個Java物件?Java物件
- 面試時如何優雅地自我介紹?面試
- 如何優雅地定位外網問題?
- 如何更優雅地切換 Git 分支Git
- Kotlin如何優雅地使用Scope FunctionsKotlinFunction
- 如何優雅地記錄操作日誌?
- 在Java中如何優雅地判空Java
- 如何優雅地處理前端異常?前端
- 如何優雅地改善程式中for迴圈
- 如何優雅地生成測試資料
- 如何優雅地記錄操作日誌