摘要:前端異常監(jiān)控如果是移除的流程,那么編程就一定是將放進(jìn)去的流程。過濾掉運(yùn)行時(shí)錯(cuò)誤上報(bào)加載錯(cuò)誤事件捕獲異常最新的規(guī)范中定義了事件用于全局捕獲對(duì)象沒有處理器時(shí)異常情況。
前端異常監(jiān)控
如果debug是移除bug的流程,那么編程就一定是將bug放進(jìn)去的流程。主要內(nèi)容
如果沒有用戶反饋問題,那就代表我們的產(chǎn)品棒棒噠,對(duì)不對(duì)?
Web規(guī)范中相關(guān)前端異常
異常按照捕獲方式分類
異常的捕獲方式
日志上報(bào)的方式
前端異常類型(Execption) WebIDL和ecma-262中的錯(cuò)誤類型
ECMAScript exceptions <==> IDL 的簡單異常
當(dāng)腳本代碼運(yùn)行時(shí)發(fā)生的錯(cuò)誤,會(huì)創(chuàng)建Error對(duì)象,并將其拋出,除了通用的Error構(gòu)造函數(shù)外,以下是另外幾個(gè)ECMAScript 2015中定義的錯(cuò)誤構(gòu)造函數(shù)。
EvalError eval錯(cuò)誤
RangeError 范圍錯(cuò)誤
ReferenceError 引用錯(cuò)誤
TypeError 類型錯(cuò)誤
URIError URI錯(cuò)誤
SyntaxError 語法錯(cuò)誤 (這個(gè)錯(cuò)誤WebIDL中故意省略,保留給ES解析器使用)
Error 通用錯(cuò)誤 (這個(gè)錯(cuò)誤WebIDL中故意省略,保留給開發(fā)者使用使用)
DOMException 最新的DOM規(guī)范定義的錯(cuò)誤類型集,兼容舊瀏覽的DOMError接口, 完善和規(guī)范化DOM錯(cuò)誤類型。
IndexSizeError 索引不在允許的范圍內(nèi)
HierarchyRequestError 節(jié)點(diǎn)樹層次結(jié)構(gòu)是不正確的。
WrongDocumentError 對(duì)象是錯(cuò)誤的
InvalidCharacterError 字符串包含無效字符。
NoModificationAllowedError 對(duì)象不能被修改。
NotFoundError 對(duì)象不能在這里被找到。
NotSupportedError 不支持的操作
InvalidStateError 對(duì)象是一個(gè)無效的狀態(tài)。
SyntaxError 字符串不匹配預(yù)期的模式
InvalidModificationError 對(duì)象不能以這種方式被修改
NamespaceError 操作在XML命名空間內(nèi)是不被允許的
InvalidAccessError 對(duì)象不支持這種操作或參數(shù)。
TypeMismatchError 對(duì)象的類型不匹配預(yù)期的類型。
SecurityError 此操作是不安全的。
NetworkError 發(fā)生網(wǎng)絡(luò)錯(cuò)誤
AbortError 操作被中止
URLMismatchError 給定的URL不匹配另一個(gè)URL。
QuotaExceededError 已經(jīng)超過給定配額。
TimeoutError 操作超時(shí)。
InvalidNodeTypeError 這個(gè)操作的 節(jié)點(diǎn)或節(jié)點(diǎn)祖先 是不正確的
DataCloneError 對(duì)象不能克隆。
前端錯(cuò)誤異常按照捕獲方式分類[x] 語法錯(cuò)誤
[x] 運(yùn)行時(shí)異常
[x] 資源加載異常
img
script
link
audio
video
iframe
...外鏈資源的DOM元素
[x] 異步請(qǐng)求異常
XMLHttpRequest
fetch
[x] Promise異常
[ ] CSS中資源異常
@font-face
background-image
...暫時(shí)無法捕獲
前端錯(cuò)誤異常的捕獲方式
try-catch (ES提供基本的錯(cuò)誤捕獲語法)
只能捕獲同步代碼的異常
回調(diào)
setTimeout
promise
window.onerror = cb (DOM0)
img
script
link
window.addEventListener("error", cb, true) (DOM2)
window.addEventListener("unhandledrejection", cb) (DOM4)
Promise.then().catch(cb)
封裝XMLHttpRequest&fetch | 覆寫請(qǐng)求接口對(duì)象
try-catch-finally將能引發(fā)異常的代碼塊放到try中,并對(duì)應(yīng)一個(gè)響應(yīng),然后有異常會(huì)被捕獲
try { // 模擬一段可能有錯(cuò)誤的代碼 throw new Error("會(huì)有錯(cuò)誤的代碼塊") } catch(e){ // 捕獲到try中代碼塊的錯(cuò)誤得到一個(gè)錯(cuò)誤對(duì)象e,進(jìn)行處理分析 report(e) } finally { console.log("finally") }onerror事件 window.onerror
當(dāng)JavaScript運(yùn)行時(shí)錯(cuò)誤(包括語法錯(cuò)誤)發(fā)生時(shí),window會(huì)觸發(fā)一個(gè)ErrorEvent接口的事件,并執(zhí)行window.onerror();
但這里有個(gè)信息要注意,語法錯(cuò)誤會(huì)導(dǎo)致出現(xiàn)語法錯(cuò)誤的那個(gè)腳本塊執(zhí)行失敗,所以語法錯(cuò)誤會(huì)導(dǎo)致當(dāng)前代碼塊運(yùn)行終止,從而導(dǎo)致整個(gè)程序運(yùn)行中斷,如果語法錯(cuò)誤這個(gè)發(fā)生在我們的錯(cuò)誤監(jiān)控語句塊中,那么我們就什么也監(jiān)控不到了。
/** * @description 運(yùn)行時(shí)錯(cuò)誤處理器 * @param {string} message 錯(cuò)誤信息 * @param {string} source 發(fā)生錯(cuò)誤的腳本URL * @param {number} lineno 發(fā)生錯(cuò)誤的行號(hào) * @param {number} colno 發(fā)生錯(cuò)誤的列號(hào) * @param {object} error Error對(duì)象 */ function err(message,source,lineno,colno,error) {...} window.onerror = errelement.onerror
當(dāng)一項(xiàng)資源(如或)加載失敗,加載資源的元素會(huì)觸發(fā)一個(gè)Event接口的error事件,并執(zhí)行該元素上的onerror()處理函數(shù)。
element.onerror = function(event) { ... } //注意和window.onerror的參數(shù)不同
注意:這些error事件不會(huì)向上冒泡到window,不過能被單一的window.addEventListener捕獲。
window.addEventListener addEventListener相關(guān)的一些內(nèi)容W3C DOM2 Events規(guī)范中提供的注冊(cè)事件監(jiān)聽器的方法, 在這之前均使用
el.onclick的形式(DOM0 規(guī)范的基本內(nèi)容,幾乎所有瀏覽器都支持)。
注意: 接口的幾種語法
error事件捕獲資源加載錯(cuò)誤資源加載失敗,不會(huì)冒泡,但是會(huì)被addEventListener捕獲,所以我們可以指定在加載失敗事件的捕獲階段捕獲該錯(cuò)誤。
注意: 接口同時(shí)也能捕獲運(yùn)行時(shí)錯(cuò)誤。
window.addEventListener("error", function(e) { var eventType = [].toString.call(e, e); if (eventType === "[object Event]") { // 過濾掉運(yùn)行時(shí)錯(cuò)誤 // 上報(bào)加載錯(cuò)誤 report(e) } }, true );unhandledrejection事件捕獲Promise異常
最新的規(guī)范中定義了 unhandledrejection事件用于全局捕獲promise對(duì)象沒有rejection處理器時(shí)異常情況。
window.addEventListener("unhandledrejection", function (event) { // ...your code here to handle the unhandled rejection... // Prevent the default handling (error in console) event.preventDefault(); });Promise.then().catch(cb).finally()
Promise中的錯(cuò)誤會(huì)被Promise.prototype.catch捕獲,所以我們通過這種方式捕獲錯(cuò)誤,這包括一些不支持unhandledrejection事件的環(huán)境中promisede polyfill實(shí)現(xiàn)。
new Promise(function(resolve, reject) { throw "Uncaught Exception!"; }).catch(function(e) { console.log(e); // Uncaught Exception! });封裝XMLHttpRequest&fetch | 覆寫請(qǐng)求接口對(duì)象
// 覆寫XMLHttpRequest API if(!window.XMLHttpRequest) return; var xmlhttp = window.XMLHttpRequest; var _oldSend = xmlhttp.prototype.send; var _handleEvent = function (event) { if (event && event.currentTarget && event.currentTarget.status !== 200) { report(event) } } xmlhttp.prototype.send = function () { if (this["addEventListener"]) { this["addEventListener"]("error", _handleEvent); this["addEventListener"]("load", _handleEvent); this["addEventListener"]("abort", _handleEvent); this["addEventListener"]("close", _handleEvent); } else { var _oldStateChange = this["onreadystatechange"]; this["onreadystatechange"] = function (event) { if (this.readyState === 4) { _handleEvent(event); } _oldStateChange && _oldStateChange.apply(this, arguments); }; } return _oldSend.apply(this, arguments); } // 覆寫fetch API if (!window.fetch) return; var _oldFetch = window.fetch; window.fetch = function() { return _oldFetch .apply(this, arguments) .then(function(res){ if (!res.ok) { // True if status is HTTP 2xx report(res) } return res; }) .catch(function(error){ report(res) }); }日志上報(bào)的方式
異步請(qǐng)求上報(bào), 后端提供接口,或者直接發(fā)到日志服務(wù)器
img請(qǐng)求上報(bào), url參數(shù)帶上錯(cuò)誤信息
eg:(new Image()).src = "http://baidu.com/tesjk?r=tksjk"
注意跨源腳本異常當(dāng)加載自不同域的腳本中發(fā)生語法錯(cuò)誤時(shí),為避免信息泄露,語法錯(cuò)誤的細(xì)節(jié)將不會(huì)報(bào)告,而代之簡單的 "Script error."
由于同源策略影響,瀏覽器限制跨源腳本的錯(cuò)誤訪問,這樣跨源腳本錯(cuò)誤報(bào)錯(cuò)信息如下圖:
在H5的規(guī)定中,只要滿足下面?zhèn)z個(gè)條件,是允許獲取跨源腳本的錯(cuò)誤信息的。
客戶端在script標(biāo)簽上增加crossorigin屬性;
服務(wù)端設(shè)置js資源響應(yīng)頭Access-Control-Origin:*(或者是域名)。
擴(kuò)展閱讀 業(yè)界已經(jīng)有的監(jiān)控平臺(tái)Sentry開源
阿里的ARMS
fundebug
FrontJS
幾個(gè)異常監(jiān)控的問題如何保證大家提交的代碼是符合預(yù)期的? 如何了解前端項(xiàng)目的運(yùn)行是否正常,是否存在錯(cuò)誤?
代碼質(zhì)量體系控制和錯(cuò)誤監(jiān)控以及性能分析
如果用戶使用網(wǎng)頁,發(fā)現(xiàn)白屏,現(xiàn)在聯(lián)系上了你們,你們會(huì)向他詢問什么信息呢?先想一下為什么會(huì)白屏?
我們以用戶訪問頁面的過程為順序,大致排查一下
用戶沒打開網(wǎng)絡(luò)
DNS域名劫持
http劫持
cdn或是其他資源文件訪問出錯(cuò)
服務(wù)器錯(cuò)誤
前端代碼錯(cuò)誤
前端兼容性問題
用戶操作出錯(cuò)
通過以上可能發(fā)生錯(cuò)誤的環(huán)節(jié),我們需要向用戶手機(jī)一下以下的用戶信息
當(dāng)前的網(wǎng)絡(luò)狀態(tài)
運(yùn)營商
地理位置
訪問時(shí)間
客戶端的版本(如果是通過客戶端訪問)
系統(tǒng)版本
瀏覽器信息
設(shè)備分辨率
頁面的來源
用戶的賬號(hào)信息
通過performance API收集用戶各個(gè)頁面訪問流程所消耗的時(shí)間
收集用戶js代碼報(bào)錯(cuò)的信息
如果我們使用了腳本代碼壓縮,然而我們又不想將sourcemap文件發(fā)布到線上,我們?cè)趺床东@到錯(cuò)誤的具體信息?
CSS文件中也存在引用資源,@font-face, background-image ...等這些請(qǐng)求錯(cuò)誤該如何進(jìn)行錯(cuò)誤捕獲?
總結(jié)
Web規(guī)范中相關(guān)前端異常
DOM處理異常
ECMAScript處理異常
異常按照捕獲方式分類
運(yùn)行時(shí)異常
資源加載異常
異步請(qǐng)求異常
Promise異常
異常的捕獲方式
try-catch (ES提供基本的錯(cuò)誤捕獲語法)
只能捕獲同步代碼的異常
回調(diào)
setTimeout
promise
window.onerror = cb (DOM0)
img
script
link
window.addEventListener("error", cb, true) (DOM2)
window.addEventListener("unhandledrejection", cb) (DOM4)
Promise.then().catch(cb)
封裝XMLHttpRequest&fetch | 覆寫請(qǐng)求接口對(duì)象
注意點(diǎn):跨源腳本異常的捕獲
日志上報(bào)的方式
異步請(qǐng)求上報(bào)
new img上報(bào) 避免跨域問題
擴(kuò)展閱讀
業(yè)界已有的異常監(jiān)控平臺(tái)
幾個(gè)跟異常監(jiān)控有關(guān)的問題
==========12月13日修正===========
語法錯(cuò)誤的捕獲有些特殊,一般情況下,語法錯(cuò)誤在開發(fā)階段就會(huì)報(bào)錯(cuò),很容易解決。但是如果在上線之后程序運(yùn)行在不兼容的環(huán)境中也可能存在語法錯(cuò)誤,引用的外部腳本存在語法錯(cuò)誤等情況,我們就可以捕獲到一個(gè)包含錯(cuò)誤信息的錯(cuò)誤對(duì)象,而不僅僅是“Uncaught SyntaxError: Invalid or unexpected token”
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99137.html
摘要:注解在類上為類提供一個(gè)全參的構(gòu)造方法,加了這個(gè)注解后,類中不提供默認(rèn)構(gòu)造方法了。這個(gè)注解用在類上,使用類中所有帶有注解的或者帶有修飾的成員變量生成對(duì)應(yīng)的構(gòu)造方法。 轉(zhuǎn)載請(qǐng)注明原創(chuàng)地址:http://www.54tianzhisheng.cn/2018/01/07/lombok/ showImg(http://ohfk1r827.bkt.clouddn.com/blog/180107/7...
摘要:手動(dòng)創(chuàng)建執(zhí)行線程存在以上問題,而線程池就是用來解決這些問題的。線程池詳解上面我們已經(jīng)知道了線程池的作用,而對(duì)于這樣一個(gè)好用,重要的工具,當(dāng)然已經(jīng)為我們提供了實(shí)現(xiàn),這也是本篇文章的重點(diǎn)。,線程池一旦空閑超過時(shí)間,線程都將被回收。 showImg(https://segmentfault.com/img/remote/1460000018476903); 本文原創(chuàng)地址,我的博客:https...
摘要:如果遇到非常的復(fù)雜的匹配,正則表達(dá)式的優(yōu)勢就更加明顯了。關(guān)于正則表達(dá)式書寫規(guī)則,可查看,上面說的很清楚了,我就不貼出來了。替換與正則表達(dá)式匹配的子串,并返回替換后的字符串。結(jié)語正則表達(dá)式并不難,懂了其中的套路之后,一切都變得簡單了。 前言 在正文開始前,先說說正則表達(dá)式是什么,為什么要用正則表達(dá)式?正則表達(dá)式在我個(gè)人看來就是一個(gè)瀏覽器可以識(shí)別的規(guī)則,有了這個(gè)規(guī)則,瀏覽器就可以幫我們判斷...
摘要:但監(jiān)聽器要在事件源上實(shí)現(xiàn)接口也就是說,直接用一個(gè)類實(shí)現(xiàn)和接口是監(jiān)聽不到內(nèi)對(duì)象的變化的。 什么是監(jiān)聽器 監(jiān)聽器就是一個(gè)實(shí)現(xiàn)特定接口的普通java程序,這個(gè)程序?qū)iT用于監(jiān)聽另一個(gè)java對(duì)象的方法調(diào)用或?qū)傩愿淖儯?dāng)被監(jiān)聽對(duì)象發(fā)生上述事件后,監(jiān)聽器某個(gè)方法將立即被執(zhí)行。。 為什么我們要使用監(jiān)聽器? 監(jiān)聽器可以用來檢測網(wǎng)站的在線人數(shù),統(tǒng)計(jì)網(wǎng)站的訪問量等等! 監(jiān)聽器組件 監(jiān)聽器涉及三個(gè)組件:事件...
閱讀 3662·2021-11-18 13:20
閱讀 2767·2021-10-15 09:40
閱讀 1801·2021-10-11 10:58
閱讀 2161·2021-09-27 13:36
閱讀 2628·2021-09-07 10:06
閱讀 1899·2021-08-11 11:21
閱讀 1459·2019-08-29 17:04
閱讀 2120·2019-08-29 14:06