首頁 web前端 js教程 處理JavaScript異常的方法

處理JavaScript異常的方法

Nov 28, 2017 am 10:05 AM
javascript js 方法

程式設計師在工作上一定會遇到的就是寫程式時會出現報錯,這篇文章是基於JavaScript中的錯誤處理部分的概念。希望在大家寫JavaScript程式的時候會幫助大家。

Demo示範

我們使用的Demo可以在GitHub下載,程式運行起來會呈現如下頁面:

處理JavaScript異常的方法

##所有的按鈕都會觸發錯誤,拋出TypeError。下面是該模組的定義:


// scripts/error.jsfunction error() {var foo = {};return foo.bar();}
登入後複製


在error()中定義了一個空物件foo,因此呼叫foo.bar()會因為未被定義而報錯。我們使用單元測試來驗證一下:


// tests/scripts/errorTest.jsit('throws a TypeError', function () {should.throws(error, TypeError);});
登入後複製

    


我們使用了Mocha配合Should.js做單元測試。

當你複製了程式碼庫並安裝了依賴套件以後,你可以使用npm t來執行測試。當然,你也可以執行某個測試文件,例如:./node_modules/mocha/bin/mocha tests/scripts/errorTest.js

相信我,像JavaScript這樣的動態語言來說,不管誰都很容易遇到這樣的錯誤。

壞的處理方式

我已經將按鈕對應的處理事件函數抽像得簡單一點,如下所示:


// scripts/badHandler.jsfunction badHandler(fn) {try {return fn();} catch (e) { }return null;}
登入後複製

badHandler接收一個fn作為回調函數,該回呼函數在badHandler中被呼叫。我們寫對應的單元測試:


// tests/scripts/badHandlerTest.jsit('returns a value without errors', function() {var fn = function()
{return 1;};var result = badHandler(fn);result.should.equal(1);});it('returns a null with errors', function() 
{var fn = function() {throw new Error('random error');};var result = badHandler(fn);should(result).equal(null);});
登入後複製

你會發現,如果出現異常,badHandler只是簡單的回傳null。如果你配合完整的程式碼,你會發現問題所在:


// scripts/badHandlerDom.js(function (handler, bomb) {var badButton = document.getElementById('bad');
if (badButton) {badButton.addEventListener('click', function () {handler(bomb);console.log('Imagine, getting promoted for hiding mistakes');});
}}(badHandler, error));
登入後複製

如果出錯的時候將其try-catch,然後僅僅返回null,我根本找不到哪裡出錯了。這種安靜失敗(fail-silent)策略可能導致UI紊亂也可能導致資料錯亂,並且在Debug的時候可能花了幾個小時卻忽略了try-catch裡面的程式碼才是致禍根源。如果程式碼複雜到有多層次的調用,簡直不可能找到哪裡出了錯。因此,我們不建議使用安靜失敗策略,我們需要更優雅的方式。

不壞但很爛的方式

// scripts/uglyHandler.jsfunction uglyHandler(fn) {try {return fn();} catch (e) {throw new Error('a new error');}}
登入後複製

它處理錯誤的方式是抓到錯誤e,然後拋出一個新的錯誤。這樣做的確優於之前安靜失敗的策略。如果出了錯,我可以一層層找回去,直到找到原本拋出的錯誤e。簡單的拋出一個Error('a new error')信息量比較有限,不精確,我們來自定義錯誤對象,傳出更多信息:

// scripts/specifiedError.js// Create a custom errorvar SpecifiedError = function SpecifiedError(message)
 {this.name = 'SpecifiedError';this.message = message || '';this.stack = (new Error()).stack;};
 SpecifiedError.prototype = new Error();SpecifiedError.prototype.constructor = SpecifiedError;
 、//  scripts/uglyHandlerImproved.jsfunction uglyHandlerImproved(fn) {try {return fn();} catch (e)
  {throw new SpecifiedError(e.message);}}// tests/scripts/uglyHandlerImprovedTest.jsit('returns a specified error with errors',
   function () {var fn = function () {throw new TypeError('type error');};should.throws(function () {uglyHandlerImproved(fn);}, 
   SpecifiedError);});
登入後複製

 


#現在,這個自訂的錯誤物件包含了原本錯誤的訊息,因此變得更加有用。但是因為再度拋出來,依然是未處理的錯誤。

截獲異常

一個想法是對所有的函數用try...catch包圍起來:


function main(bomb) {try {bomb();} catch (e) {// Handle all the error things}}
登入後複製

但是,這樣的程式碼將會變得非常臃腫、不可讀,而且效率低。是否還記得?在本文開始我們有提到在JavaScript中異常不過也是一個事件而已,幸運的是,有一個全域的異常事件處理方法(onerror)。

// scripts/errorHandlerDom.jswindow.addEventListener('error', function (e) {var error = e.error;console.log(error);});
登入後複製

取得堆疊資訊

你可以將錯誤訊息傳送到伺服器:


// scripts/errorAjaxHandlerDom.jswindow.addEventListener('error', function (e)
{var stack = e.error.stack;var message = e.error.toString();if (stack) {message += '\n' + stack;}
var xhr = new XMLHttpRequest();xhr.open('POST', '/log', true);// Fire an Ajax request with error detailsxhr.send(message);});
登入後複製

為了取得更詳細的報錯訊息,並且省去處理資料的麻煩,你也可以使用fundebug的JavaScript監控外掛三分鐘快速接取bug監控服務。

下面是伺服器接收到的報錯訊息:

處理JavaScript異常的方法

如果你的腳本是放在另一個網域下,如果你不開啟CORS,除了Script error.,你將看不到任何有用的報錯資訊。如果想知道具體解法,請參考:Script error.全面解析。

非同步錯誤處理

由於setTimeout非同步執行,下列的程式碼例外狀況將不會被try...catch捕捉:


// scripts/asyncHandler.jsfunction asyncHandler(fn) {try {// This rips the potential bomb from the current contextsetTimeout(function () {fn();}, 1);} catch (e) { }}
登入後複製

  

try...catch語句只會捕捉目前執行環境下的例外狀況。但是在上面異常拋出的時候,JavaScript解釋器已經不在try...catch中了,因此無法被捕獲。所有的Ajax請求也是這樣。

我們可以稍微改進一下,將try...catch寫到非同步函數的回呼中:


setTimeout(function () {try {fn();} catch (e) {// Handle this async error}}, 1);
登入後複製

 

不過,這樣的套路會導致項目中充滿了try...catch,程式碼非常不簡潔。並且,執行JavaScript的V8引擎不鼓勵在函數中使用try...catch。好在,我們不需要這麼做,全域的錯誤處理onerror會捕捉這些錯誤。

結論

我的建議是不要隱藏錯誤,勇敢地拋出。沒有人會因為程式碼出現bug而導致程式崩潰而羞恥,我們可以讓程式中斷,讓用戶重來。錯誤是無法避免的,如何去處理它才是最重要的。

以上內容就是處理JavaScript報錯時的方法,大家覺得有用的話,趕緊收藏起來吧。

相關推薦:

如何解決vue.js在撰寫過程中出現空格不規範報錯的問題

##完美解決php安裝擴充mysqli的實作步驟及報錯

MySQL資料庫封包錯誤:Too many connections的解決方法

以上是處理JavaScript異常的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

怎麼在番茄免費小說app中寫小說 分享番茄小說寫小說方法教程 怎麼在番茄免費小說app中寫小說 分享番茄小說寫小說方法教程 Mar 28, 2024 pm 12:50 PM

番茄小說是一款非常熱門的小說閱讀軟體,我們在番茄小說中經常會有新的小說和漫畫可以去閱讀,每一本小說和漫畫都很有意思,很多小伙伴也想著要去寫小說來賺取賺取零用錢,在把自己想要寫的小說內容編輯成文字,那麼我們要怎麼樣在這裡面去寫小說呢?小伙伴們都不知道,那就讓我們一起到本站本站中花點時間來看寫小說的方法介紹。分享番茄小說寫小說方法教學  1、先在手機上打開番茄免費小說app,點擊個人中心——作家中心  2、跳到番茄作家助手頁面——點擊創建新書在小說的結

七彩虹主機板怎麼進入bios?教你兩種方法 七彩虹主機板怎麼進入bios?教你兩種方法 Mar 13, 2024 pm 06:01 PM

  七彩虹主機板在中國國內市場享有較高的知名度和市場佔有率,但是有些七彩虹主機板的用戶還不清楚怎麼進入bios進行設定呢?針對這一情況,小編專門為大家帶來了兩種進入七彩虹主機板bios的方法,快來試試吧!方法一:使用u盤啟動快捷鍵直接進入u盤裝系統七彩虹主機板一鍵啟動u盤的快捷鍵是ESC或F11,首先使用黑鯊裝機大師製作一個黑鯊U盤啟動盤,然後開啟電腦,當看到開機畫面的時候,連續按下鍵盤上的ESC或F11鍵以後將會進入到一個啟動項順序選擇的窗口,將遊標移到顯示“USB”的地方,然

微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) 微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) May 01, 2024 pm 12:01 PM

而後悔莫及、人們常常會因為一些原因不小心刪除某些聯絡人、微信作為一款廣泛使用的社群軟體。幫助用戶解決這個問題,本文將介紹如何透過簡單的方法找回被刪除的聯絡人。 1.了解微信聯絡人刪除機制這為我們找回被刪除的聯絡人提供了可能性、微信中的聯絡人刪除機制是將其從通訊錄中移除,但並未完全刪除。 2.使用微信內建「通訊錄恢復」功能微信提供了「通訊錄恢復」節省時間和精力,使用者可以透過此功能快速找回先前刪除的聯絡人,功能。 3.進入微信設定頁面點選右下角,開啟微信應用程式「我」再點選右上角設定圖示、進入設定頁面,,

Win11管理員權限取得方法總計 Win11管理員權限取得方法總計 Mar 09, 2024 am 08:45 AM

Win11管理員權限取得方法匯總在Windows11作業系統中,管理員權限是非常重要的權限之一,可以讓使用者對系統進行各種操作。有時候,我們可能需要取得管理員權限來完成一些操作,例如安裝軟體、修改系統設定等。下面就為大家總結了一些取得Win11管理員權限的方法,希望能幫助大家。 1.使用快捷鍵在Windows11系統中,可以透過快捷鍵的方式快速開啟命令提

手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) 手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) May 04, 2024 pm 06:01 PM

手機遊戲成為了人們生活中不可或缺的一部分,隨著科技的發展。它以其可愛的龍蛋形象和有趣的孵化過程吸引了眾多玩家的關注,而其中一款備受矚目的遊戲就是手機版龍蛋。幫助玩家們在遊戲中更好地培養和成長自己的小龍,本文將向大家介紹手機版龍蛋的孵化方法。 1.選擇合適的龍蛋種類玩家需要仔細選擇自己喜歡並且適合自己的龍蛋種類,根據遊戲中提供的不同種類的龍蛋屬性和能力。 2.提升孵化機的等級玩家需要透過完成任務和收集道具來提升孵化機的等級,孵化機的等級決定了孵化速度和孵化成功率。 3.收集孵化所需的資源玩家需要在遊戲中

手機字體大小設定方法(輕鬆調整手機字體大小) 手機字體大小設定方法(輕鬆調整手機字體大小) May 07, 2024 pm 03:34 PM

字體大小的設定成為了重要的個人化需求,隨著手機成為人們日常生活的重要工具。以滿足不同使用者的需求、本文將介紹如何透過簡單的操作,提升手機使用體驗,調整手機字體大小。為什麼需要調整手機字體大小-調整字體大小可以使文字更清晰易讀-適合不同年齡段用戶的閱讀需求-方便視力不佳的用戶使用手機系統自帶字體大小設置功能-如何進入系統設置界面-在在設定介面中找到並進入"顯示"選項-找到"字體大小"選項並進行調整第三方應用調整字體大小-下載並安裝支援字體大小調整的應用程式-開啟應用程式並進入相關設定介面-根據個人

Oracle版本查詢方法詳解 Oracle版本查詢方法詳解 Mar 07, 2024 pm 09:21 PM

Oracle版本查詢方法詳解Oracle是目前世界上最受歡迎的關聯式資料庫管理系統之一,它提供了豐富的功能和強大的效能,廣泛應用於企業。在進行資料庫管理和開發過程中,了解Oracle資料庫的版本是非常重要的。本文將詳細介紹如何查詢Oracle資料庫的版本信息,並給出具體的程式碼範例。查詢資料庫版本的SQL語句在Oracle資料庫中,可以透過執行簡單的SQL語句

快速掌握:華為手機開啟兩個微信帳號方法大揭密! 快速掌握:華為手機開啟兩個微信帳號方法大揭密! Mar 23, 2024 am 10:42 AM

在現今社會,手機已經成為我們生活中不可或缺的一部分。而微信作為我們日常溝通、工作、生活的重要工具,更是經常被使用。然而,在處理不同事務時可能需要分開兩個微信帳號,這就要求手機能夠支援同時登入兩個微信帳號。華為手機作為國內知名品牌,很多人使用,那麼華為手機開啟兩個微信帳號的方法是怎麼樣的呢?下面就來揭秘一下這個方法。首先,要在華為手機上同時使用兩個微信帳號,最簡

See all articles