JavaScript區域性錯誤處理、全域性錯誤處理及錯誤上報模組設計
JavaScript引擎執行JavaScript程式碼時,會發生各種錯誤:可能是語法或拼寫錯誤,可能是瀏覽器差異(使用了瀏覽器特有功能),也可能是伺服器返回異常未處理,當然還有許多其它不可預知的因素。當錯誤發生時,JavaScript 引擎會中斷後續程式碼執行,並生成一個錯誤訊息。為了使程式碼更健壯,避免程式碼意外中斷,我們需要處理各種異常。
1、區域性錯誤處理
區域性錯誤處理指程式碼可能出錯的地方進行錯誤捕捉處理,需要程式猿進行硬code,JavaScript錯誤處理相關有4條語句:
1)try, catch語句,錯誤捕捉語句
2)finall語句,錯誤捕捉處理後,return前制執行語句
3)throw語句,錯誤丟擲語句
案例1:
try {
window.abcdefg();
} catch (e) {
alert('發生錯誤啦,錯誤資訊為:' e.message);
} finally {//總是會被執行
alert('我都會執行!');
}
控制檯輸出:
發生錯誤啦,錯誤資訊為: window.abcdefg is not a function
我都會執行
finally語句在catch後,return前執行。
案例2,引自w3school.
<!DOCTYPE html>
<html>
<head>
<meta http- equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Throw Demo</title>
</head>
<body>
<script>
function myFunction()
{
try
{
var x=document.getElementById("demo").value;
if(x=="") throw "不能為空";
if(isNaN(x)) throw "不是有效數字";
if(x>10) throw "不能大於10" ;
if(x<5) throw "不能小於5";
} catch(err) {
var y=document.getElementById("mess");
y.innerHTML="Error: " + err + ".";
}
}
</script>
<p>請輸入一個5到10的數字:</p>
<input id="demo" type="text">
<button type="button" onclick="myFunction()">Test Input</button>
<p id="mess"></p>
</body>
</html>
throw的作用就是將可預見或不可預見的錯誤轉義成使用者可認知的錯誤。
2、全域性錯誤處理
由於前端開發人員水平不一、程式碼規範程度不一,不是所有JavaScript程式碼都有錯誤處理。因此,JavaScript程式碼在執行過程中常常會因為不可預見異常而導致程式碼意外終止,為此,我們需要全域性捕捉錯誤異常,並及時提醒開發人員修改程式碼。只要繫結window.onerrot事件即可進行頁面全域性js error錯誤處理,程式碼如下:
function globalErrorHandle(msg,url,l,c,error) {
console.error("global js error: ", msg, l);
// TODO other things.
}
window.onerror = globalErrorHandle;
繫結window.onerrot事件,js報錯就會呼叫globalErrorHandle,其中:
- msg:錯誤訊息
- url:報錯頁面url
- l:程式碼報錯行號
- c: 列號
- error: 錯誤物件
把上文的案例1,用全域性錯誤來捕捉,程式碼如下圖:
控制檯輸出:
3、錯誤上報模組設計
全域性錯誤處理並不能阻塞程式碼意外終止,也就是說當js執行過程中報錯又沒有try-catch錯誤處理,則會呼叫globalErrorHandle,但是後續程式碼會意外終止不再執行。因此,全域性錯誤處理更多是全域性錯誤記錄並上報。通常做3個事情:
- globalErrorHandle,全域性錯誤捕捉;
- 將錯誤資訊上報到伺服器(報錯頁面、行號、列號等);
- 管理員在伺服器上發現js錯誤資訊時,責令相關人員修改;
看個案例,截圖如下:
上圖就是一個簡單的js錯誤上報模組,錯誤檢視頁面,資訊包括:錯誤源(哪個頁面),錯誤描述,行號,作業系統+瀏覽器,操作人,操作時間等。
有幾個注意事項:
1)上報內容過濾
如上圖所示,好多錯誤資訊都是一樣的,如果在某個大迴圈裡不斷的在觸發錯誤,則會不斷向伺服器傳送錯誤資訊,因此錯誤資訊傳送前先做過濾,操作如下:
- 頁面載入時,先獲取 錯誤源+錯誤描述 hashcode 去重列表;
- 全域性錯誤捕捉時,生成的錯誤源+錯誤描述 hashcode是否已經存在,不存在則上報錯誤訊息;
2)上報哪些內容
為了錯誤重現,建議儘可能使錯誤資訊詳細,至少應包含:
- 錯誤頁面url
- 錯誤描述、錯誤行號、列號、stack資訊
- 瀏覽器和作業系統資訊
- 操作時間,甚至操作人、引數