摘要:錯誤處理在開發和調試過程中都顯得尤為重要。跟全局函數有關的錯誤,在之后已經不再出現了內部錯誤。由引擎拋出的錯誤范圍錯誤。事件任何沒有的錯誤都會觸發對象的事件。事件可以接收三個參數錯誤消息錯誤所在的和行號。
錯誤處理在開發和調試過程中都顯得尤為重要。有些沒有進行錯誤處理的應用,直接就將瀏覽器的錯誤展示給了用戶,極大的降低了用戶體驗。比如有些很 low 的網站,打開某些頁面就直接彈出 "object" 這樣的錯誤,用戶看到之后一臉懵逼,心想這是什么鬼?讓人感覺極其的不專業。可見錯誤處理對一個應用來說是多么的重要。
這篇文章主要是給大家科普一些關于錯誤處理的知識,讓大家在腦海中有一個概覽。下一篇文章中我會結合具體的項目以及當前主流的一些框架,比如react, redux,來更深入的介紹如何運用這些框架去封裝一整套錯誤處理的解決方案。
error 對象Error 構造對象可以實例化一個 error 對象 (也就是Error 實例),而 error 對象就是一個包含了錯誤信息的對象。當代碼解析或者運行時發生錯誤,javascript 引擎就會自動產生并拋出一個 error 對象, 然后程序就中斷在發生錯誤的地方。
示例:
const error = new Error("Whoop!"); error.message; // Whoop! error.name; // Error error.stack; // "Error: Whoops! at:1:13"
我們常用的 message 和 name 都是 error 的標準屬性,由于各個瀏覽器廠商對 error 進行了不同的擴展,所以在不同的瀏覽器中,error 也有不同的屬性和方法, 非標準屬性中我們常用的是 stack 屬性(很多瀏覽器都擴展了這一屬性), 它用來表示棧跟蹤信息。
屬性 | 含義 |
---|---|
message | 錯誤信息 |
name | 錯誤類型 |
constructor | 指定一個函數用來創建實例的原型,也就是指定構造器(創建自定義 Error 會用到) |
stack (非標準) | 棧跟蹤信息 |
除了普通的 Error 構造對象以外, javascript 還實現了其他幾種主要的 error 構造對象1.
類型 | 解析 | 實例 |
---|---|---|
EvalError | eval錯誤。跟全局函數 eval() 有關的錯誤,在 ES5 之后已經不再出現了 | |
InternalError | 內部錯誤。由 JavaScript 引擎拋出的錯誤 | |
RangeError | 范圍錯誤。發生在一個數值或參數超出其合法范圍,主要包括超出數組范圍或者超出數字取值范圍 | new Array(-1); (1234).toExponential(21); |
ReferenceError | 引用錯誤。通常是由于引用了一個不存在的值。 | a.toString(); |
SyntaxError | 語法錯誤。 | a ? a+1; |
TypeError | 類型錯誤。通常是因為在執行特定的類型操作時,變量的類型不符合要求。例如變量中保存著意外類型,訪問不存在的方法等。 | var a = new {}; var a = {a:1}; a.reverse(); // 對象并沒有 reverser 方法 |
URIError | decodeURI() 或者 encodeURI() 傳入非法參數時,也包括 encodeURIComponent() 和 decodeURIComponent() | decodeURI("http://www.test.com&%"); encodeURIComponent("uD800"); |
這里順便說一下 encodeURI 和 encodeURIComponent 的區別。已經了解的同學可以忽略這一小部分,繼續往前面看。
encodeURI 是對統一資源標識符 (URI) 全部編碼,而 encodeURIComponent 對統一資源標識符 (URI) 部分編碼。
假設一個 URI 是一個完整的 URI, 那么我們不必對那些在 URI 中保留的并且帶有特殊含義的字符進行編碼。由于 encodeURI 會替換掉所有字符,但是卻不包含一些保留字符,如 "&", "+", "=" 等(這些字符在 GET 和 POST 請求中是特殊字符,需要被編碼),所以 encodeURI 本身無法產生能使用與 HTTP GET 或者 POST 請求的 URI。但是我們可以使用 encodeURIComponent 來對這些字符進行編碼。
encodeURIComponent 轉義除了字母、數字、(、)、.、!、~、*、"、-和_之外的所有字符。拋出和捕獲錯誤 throw and try...catch
為了避免服務器收到不可預知的請求,對任何用戶輸入的作為 URI 部分的內容都需要用 encodeURIComponent 進行轉義。
通常使用 throw 語句拋出錯誤,并用 try...catch 進行捕獲。通常會把所有可能會拋出錯誤的代碼都放在 try 語句塊中,而把那些用于錯誤處理的代碼放在 catch 塊中。
throw 語句throw 過程是阻塞的,程序會中斷在第一個拋出錯誤的地方,所以后面的代碼不會執行。
throw new SyntaxError("this is syntax error"); throw 123; // 不執行 throw "hi there"; // 不執行 throw true; // 不執行catch 語句
catch 代碼塊捕獲錯誤之后,程序不會中斷,會按照正常流程繼續執行下去。
try { throw new Error("Whoops!"); } catch (e) { console.log(e.name + ":" + e.message); } console.log("hello!"); // Error:Whoops! // hello!finally 語句
finally 在 try...catch 中是可選的,但是一旦使用了它,它里面的代碼就一定會被執行,也就是說不管 try 語句塊中的代碼是否正常執行,finnaly 都會被執行。正如下面的代碼, 即使在 try 中資源被阻塞,由于我們在 finnaly 中執行了關閉操作,文件最后還是會被關閉。
openMyFile() try { // 阻塞資源 writeMyFile(theData); } finally { closeMyFile(); // 始終會關閉資源 }
處理一個特定的錯誤。
try { foo.bar(); } catch (e) { switch (e.name) { case "RangeError": //do something console.log("RangeError: " + e.message); break; case "ReferenceError": //do something console.log("ReferenceError: " + e.message); break; default: console.log(e.name + ":" + e.message); } }error 事件
任何沒有 catch 的錯誤都會觸發 window 對象的 error 事件。
error 事件可以接收三個參數:錯誤消息、錯誤所在的 URL 和行號。你可以通過以下兩種方式給 window 綁上 error 事件2。
// message: 錯誤消息, source: 發生錯誤文件的 URL, lineno: 錯誤行號 // 方法一 window.onerror = function(messageOrEvent, source, lineno, colno, error) { alert(messageOrEvent, source, lineno, colno, error); } or window.onerror = console.log; throw new Error("whoops!"); // 方法二 window.addEventListener("error", function(errorEvent){ alert(errorEvent.error); });
在實際情況中,error 事件并不常用(但是在某些情況下,如微信端的調試,error 事件還是挺有用的),因為我們還是希望所有的異常都能得到很好的處理,而不是把錯誤交給瀏覽器。但有的時候并不是所有的錯誤都能夠被撲獲,并且某些業務場景會使用到追蹤瀏覽器報錯的工具,這時候可能就需要將瀏覽器的錯誤拋出去,所以在這種情況下也需要去全局監聽 error 事件。
自定義錯誤類型 Custom Error Types創建一個自定義類 CustomError, 以方便去擴展更多的自定義 Error
CustomError.js
class CustomError extends Error { constructor(message) { super(message); this.name = this.constructor.name; if (typeof Error.captureStackTrace === "function") { // 在瀏覽器領域,除了使用V8引擎的 Chrome, // 其它瀏覽器中不存在 Error.captureStackTrace()這一接口, // 所以在這里做一個條件判斷。 Error.captureStackTrace(this, this.constructor); // 返回調用堆棧信息, 用于在 error 對象上添加合理的 stack 屬性。 } else { this.stack = new Error(message).stack; } } }Error.captureStackTrace
Error.captureStackTrace 是用來在 targetObject 中添加一個 .stack 屬性。對該屬性進行訪問時,將以字符串的形式返回 Error.captureStackTrace() 語句被調用時的代碼位置信息(即:調用棧歷史)。
Error.captureStackTrace(targetObject[, constructorOpt])
除了 targetObject, captureStackTrace 還接受一個類型為 function 的可選參數 constructorOpt,當傳遞該參數時,調用棧中所有 constructorOpt 函數之上的信息(包括 constructorOpt 函數自身),都會在訪問 targetObject.stack 時被忽略。當需要對終端用戶隱藏內部的技術細節時, constructorOpt 參數會很有用。
擴展自定義 Error 類型通過基類 CustomError,我們可以創建出更多的自定義 Error, 比如下面的 HttpRequestError 和 LoginExpiredError
HttpRequestError.js
class HttpRequestError extends CustomError { constructor(message, requestId, code, httpStatusCode) { const defaultAPIErrorMessage = () => { // 檢查是否有網 return window.navigator.onLine ? "Something wrong" : "No connection"; }; message = message || defaultAPIErrorMessage(); super(message); this.requestId = requestId; this.code = code; this.httpStatusCode = httpStatusCode; } } throw new HttpRequestError(null, "requestId", "code", "httpStatusCode");
LoginExpiredError.js
class LoginExpiredError extends CustomError { constructor(message) { message = message || "Your session has expired!"; super(message); } } throw new LoginExpiredError();
當我們創建了各種自定義 Error 之后,我們可以在不同的場景去使用它們了,比如在 http 請求失敗的時候拋出 HttpRequestError,并彈出對話框提示用戶。在用戶登錄過期之后,拋出 LoginExpiredError,彈出對話框,并自動 logout 等等。通過拋出不同的 Error 類型,才能讓我們進行不同的撲獲處理。
const deffer = Q.deffer(); if (expired) { deffer.reject(new LoginExpiredError()); // 通過 promise 拋出異常 } if (error instanceof LoginExpiredError) { // 撲獲異常 logout(); }結尾
關于 Error 的介紹就先講到這里。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88005.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:強制類型轉換本章介紹了的數據類型之間的轉換即強制類型轉換包括顯式和隱式。強制類型轉換常常為人詬病但實際上很多時候它們是非常有用的。隱式強制類型轉換則沒有那么明顯是其他操作的副作用。在處理強制類型轉換的時候要十分小心尤其是隱式強制類型轉換。 前言 《你不知道的 javascript》是一個前端學習必讀的系列,讓不求甚解的JavaScript開發者迎難而上,深入語言內部,弄清楚JavaSc...
摘要:摘要的錯誤監控插件同步支持異步錯誤監控。此次更新,我們對的監控插件做了相應的更新,來更好地支持使用框架開發的應用錯誤的監控。程序運行后,成功捕獲該錯誤總結更新到,對錯誤處理提供了更加強大的支持。 摘要: Fundebug 的 JavaScript 錯誤監控插件同步支持 Vue.js 異步錯誤監控。 Vue.js 從誕生至今已經 5 年,尤大在今年 2 月份發布了重大更新,即Vue 2....
摘要:工作機制第部分本文轉載自眾成翻譯譯者網絡埋伏紀事鏈接原文隨著越來越受歡迎,開發團隊正在將其用在技術棧的各個方面,包括前端后端混合應用嵌入式設備等等。之后,步驟將是如下這樣調用棧中的每個條目稱為棧幀。 JavaScript工作機制:第1部分 本文轉載自:眾成翻譯譯者:網絡埋伏紀事鏈接:http://www.zcfy.cc/article/3965原文:https://blog.sessi...
摘要:通過使用提供的異常處理語句,可以用結構化的方式來捕捉發生的錯誤,讓異常處理帶啊與核心業務代碼實現分離。錯誤與異常處理在應用中的重要性是毋庸置疑的。包括內置對象函數在內的所有函數都可以用來調用,這種函數調用被稱為構造函數調用。 錯誤與異常 概念 錯誤與異常是什么錯誤,指程序中的費正常運行狀態,在其他編程語言中稱為‘異常’或‘錯誤’。解釋器會為每一個錯誤創建并拋出一個Error對象,其中包...
閱讀 2261·2021-10-09 09:41
閱讀 3409·2021-09-13 10:34
閱讀 1920·2019-08-30 12:59
閱讀 557·2019-08-29 17:27
閱讀 1063·2019-08-29 16:07
閱讀 2956·2019-08-29 13:15
閱讀 1306·2019-08-29 13:14
閱讀 1562·2019-08-26 12:18