騰訊雲技術社區-掘金主頁持續爲你們呈現雲計算技術文章,歡迎你們關注!javascript
做者:vienwuhtml
javascript的出錯咱們應該都很熟悉,例如xxx undefined
,SyntaxError
等。java
咱們team將出現錯誤的javascript代碼取名爲badjs,也有一個開源的badjs項目,用於捕獲和分析js錯誤,並提供了一些基礎的報表數據分析。git
try{...}catch(e){...}
包裹須要執行的代碼,獲取error對象的屬性定位錯誤並上報第一種方式最簡單,但當執行的js代碼和咱們的站點在不一樣域即跨域時,因爲瀏覽器的安全限制,onerror()方法只能捕獲到一個固定的錯誤代碼Script error.
。
具體可參考這裏:點擊查看github
咱們團隊目前的業務基本都會將靜態資源部署到cdn服務器,和站點處於不一樣域,因此須要解決跨域問題。web
跨域問題能夠經過服務器端設置access-control-allow-orgin:*
解決,但並不完美。這個問題更深刻的信息能夠參考這裏:github.com/BetterJS/ba…ajax
第二種方式是手動包裹一些要檢測的代碼,沒有跨域問題而且能夠獲取到err的對象的詳細出錯信息。
這種方式相對麻煩一些,但能夠經過全局的hook,處理大部分狀況,免除每次手動寫try...catch的煩惱。正則表達式
咱們都知道js代碼的執行是經過事件和定時器觸發執行的,因此理論上將事件觸發時的回調、定時器的回調包裹便可。api
咱們的badjs項目主要是經過第二種方式實現,並根據現有的業務,對如下幾種方法進行了處理:跨域
define()
,require()
等方法$.event.add
,$.event.remove
,ajax等這裏處理的原理比較簡單,相似下面的代碼:
function define(){
...
}
var a = define;
define = function(){
try{
a.apply(this,arguments);
}catch(e){
...錯誤上報
}
};複製代碼
這裏還有一些兼容性的問題須要處理,例如在ie低版本中setTimtout和setInterval方法並非function
類型,而是object
,因此沒法使用改寫function
的方式進行包裹。相似的還有document.attachEvent
方法也是object
,不是function
。
除了對以上方法的單獨處理外,還有一些意外狀況沒法處理,例如:
這些意外狀況很難作全局的hook,因此只好手動try...catch。
咱們的badjs也提供了一個便捷的api,例如源代碼是這樣:
var img = new Image();
img.onload = function(){
...
};複製代碼
使用tryjs包裹
var img = new Image();
img.onload = tryJs.spyCustom(function(){
...
});複製代碼
除此以外,try...catch能獲取的err對象在各不一樣的瀏覽器之間,也有一些差別。好在有人已經作一個頁面展現詳細的差別,參考url: broofa.com/tests/Error…
回到捕獲js錯誤這件事自己,是爲了更好的監控並定位錯誤,幫助咱們改善代碼質量,因此kael也提到另一個思路,能夠灰度一部分用戶,直接使用主域而不是cdn的js,直接避免跨域問題
,這個思路也值得一試。
另外,錯誤上報數據和訪問量等數據若是到結合一塊兒分析,不只能夠更快速的定位問題,甚至能夠實現監控自動告警等,固然這個也很是複雜。
相關推薦
移動端tryjs異常捕獲
新用戶850元大禮包,輕鬆上雲
玩轉JavaScript正則表達式
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處
原文連接:www.qcloud.com/community/a…
獲取更多騰訊海量技術實踐乾貨,歡迎你們前往騰訊雲技術社區