您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了Node.js API中如何使用Error模塊,內(nèi)容簡而易懂,希望大家可以學(xué)習(xí)一下,學(xué)習(xí)完之后肯定會有收獲的,下面讓小編帶大家一起來看看吧。
Node.js API詳解之 Error
Node.js 中運行的應(yīng)用程序一般會遇到以下四類錯誤:
1.標(biāo)準(zhǔn)的 JavaScript 錯誤:
EvalError : 當(dāng)調(diào)用 eval() 失敗時拋出。
SyntaxError : 當(dāng) JavaScript 語法錯誤時拋出。
RangeError : 當(dāng)值不在預(yù)期范圍內(nèi)時拋出。
ReferenceError : 當(dāng)使用未定義的變量時拋出。
TypeError : 當(dāng)傳入錯誤類型的參數(shù)時拋出。
URIError : 當(dāng)全局的 URI 處理函數(shù)被誤用時拋出。
2.由底層操作系觸發(fā)的系統(tǒng)錯誤,例如試圖打開一個不存在的文件、試圖通過一個已關(guān)閉的 socket 發(fā)送數(shù)據(jù)等。
3.由應(yīng)用程序代碼觸發(fā)的用戶自定義的錯誤。
4.斷言錯誤是錯誤的一個特殊類別,每當(dāng) Node.js 檢測到一個不應(yīng)該發(fā)生的異常邏輯時觸發(fā)。 這類錯誤通常由 assert 模塊引起。
所有由 Node.js 引起的 JavaScript 錯誤與系統(tǒng)錯誤都繼承自或?qū)嵗詷?biāo)準(zhǔn)的 JavaScript 類,且保證至少提供類中的屬性。
說明:
Node.js 支持幾種當(dāng)應(yīng)用程序運行時發(fā)生的錯誤的冒泡和處理的機制。
如何報告和處理這些錯誤完全取決于錯誤的類型和被調(diào)用的 API 的風(fēng)格。
所有 JavaScript 錯誤都會被作為異常處理,異常會立即產(chǎn)生并使用標(biāo)準(zhǔn)的 JavaScript throw 機制拋出一個錯誤。
這些都是使用 JavaScript 語言提供的 try / catch 語句處理的。
JavaScript 的 throw 機制的任何使用都會引起異常,異常必須使用 try / catch 處理,
否則 Node.js 進(jìn)程會立即退出。
除了少數(shù)例外,同步的 API(任何不接受 callback 函數(shù)的阻塞方法,例如 fs.readFileSync)會使用 throw 報告錯誤。
大多數(shù)的異步方法都接受一個 callback 函數(shù),該函數(shù)會接受一個 Error 對象傳入作為第一個參數(shù)。
如果第一個參數(shù)不是 null 而是一個 Error 實例,則說明發(fā)生了錯誤,應(yīng)該進(jìn)行處理。例:
const fs = require('fs'); fs.readFile('一個不存在的文件', (err, data) => { if (err) { console.error('讀取文件出錯!', err); return; } // 否則處理數(shù)據(jù) });
當(dāng)一個異步方法被一個 EventEmitter 對象調(diào)用時,錯誤會被分發(fā)到對象的 ‘error' 事件上。例:
const net = require('net'); const connection = net.connect('localhost'); // 添加一個 'error' 事件句柄到一個流: connection.on('error', (err) => { // 如果連接被服務(wù)器重置,或無法連接,或發(fā)生任何錯誤,則錯誤會被發(fā)送到這里。 console.error(err); }); connection.pipe(process.stdout);
Node.js API 中有一小部分普通的異步方法仍可能使用 throw 機制拋出異常,且必須使用 try / catch 處理。
這些方法并沒有一個完整的列表;請參閱各個方法的文檔以確定所需的合適的錯誤處理機制。
對于所有的 EventEmitter 對象,如果沒有提供一個 ‘error' 事件句柄,則錯誤會被拋出,
并造成 Node.js 進(jìn)程報告一個未處理的異常且隨即崩潰,除非: 適當(dāng)?shù)厥褂?domain 模塊或已經(jīng)注冊了一個 process.on(‘uncaughtException') 事件的句柄。
const EventEmitter = require('events'); const ee = new EventEmitter(); setImmediate(() => { // 這會使進(jìn)程崩潰,因為還為添加 'error' 事件句柄。 ee.emit('error', new Error('這會崩潰')); });
這種方式產(chǎn)生的錯誤無法使用 try / catch 截獲,因為它們是在調(diào)用的代碼已經(jīng)退出后拋出的。
開發(fā)者必須查閱各個方法的文檔以明確在錯誤發(fā)生時這些方法是如何冒泡的。
說明:
一個通用的 JavaScript Error 對象,它不表示錯誤發(fā)生的具體情況。
Error 對象會捕捉一個“堆棧跟蹤”,詳細(xì)說明被實例化的 Error 對象在代碼中的位置,并可能提供錯誤的文字描述。
只對于加密,如果在拋出錯誤時可以使用 Error 對象,則會將OpenSSL錯誤堆棧放入到名為 opensslErrorStack 的單獨屬性中。
所有由 Node.js 產(chǎn)生的錯誤,包括所有系統(tǒng)的和 JavaScript 的錯誤都實例化自或繼承自 Error 類。
說明:
新建一個 Error 實例,并設(shè)置 error.message 屬性以提供文本信息。
如果 message 傳的是一個對象,則會調(diào)用 message.toString() 生成文本信息。
error.stack 屬性表示被調(diào)用的 new Error() 在代碼中的位置。
堆棧跟蹤是基于 V8 的堆棧跟蹤 API 的。
堆棧跟蹤只會?。╝)異步代碼執(zhí)行的開頭或(b)Error.stackTraceLimit 屬性給出的棧幀中的最小項。
demo:
throw new Error('異常信息'); // Error: 異常信息 // at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:1:69) // at Module._compile (module.js:660:30) // at Object.Module._extensions..js (module.js:671:10) // at Module.load (module.js:573:32) // at tryModuleLoad (module.js:513:12) // at Function.Module._load (module.js:505:3) // at Function.Module.runMain (module.js:701:10) // at startup (bootstrap_node.js:193:16) // at bootstrap_node.js:617:3
說明:
Error.stackTraceLimit 屬性指定了堆棧跟蹤收集的棧幀數(shù)量
(無論是 new Error().stack 或 Error.captureStackTrace(obj) 產(chǎn)生的)。
默認(rèn)值為 10 ,但可設(shè)為任何有效的 JavaScript 數(shù)值。 值改變后的變化會影響所有捕獲到的堆棧跟蹤。
如果設(shè)為一個非數(shù)值或負(fù)數(shù),則堆棧跟蹤不會捕捉任何棧幀。
demo:
Error.stackTraceLimit = 5; try{ const a = 1 + b; }catch(err){ console.log(err.stack); } // ReferenceError: b is not defined // at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:3:16) // at Module._compile (module.js:660:30) // at Object.Module._extensions..js (module.js:671:10) // at Module.load (module.js:573:32) // at tryModuleLoad (module.js:513:12)
說明:
在 targetObject 上創(chuàng)建一個 .stack 屬性
當(dāng)訪問時返回一個表示代碼中調(diào)用 Error.captureStackTrace() 的位置的字符串。
可選的 constructorOpt 參數(shù)接受一個函數(shù)。 如果提供了,則 constructorOpt 之上包括自身在內(nèi)的全部棧幀都會被生成的堆棧跟蹤省略。
demo:
const myObject = {}; Error.captureStackTrace(myObject); console.log( myObject.stack ); // Error // at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:2:7) // at Module._compile (module.js:660:30) // at Object.Module._extensions..js (module.js:671:10) // at Module.load (module.js:573:32) // at tryModuleLoad (module.js:513:12) // at Function.Module._load (module.js:505:3) // at Function.Module.runMain (module.js:701:10) // at startup (bootstrap_node.js:193:16) // at bootstrap_node.js:617:3
說明:
error.code 屬性是標(biāo)識錯誤類別的字符標(biāo)簽。
詳見 Node.js Error Codes
demo: try{ const a = 1 + b; }catch(err){ console.log(err.code); } // undefined
error.message
說明:
error.message 屬性是錯誤的字符串描述,通過調(diào)用 new Error(message) 設(shè)置。
傳給構(gòu)造函數(shù)的 message 也會出現(xiàn)在 Error 的堆棧跟蹤的第一行。
但是,Error 對象創(chuàng)建后改變這個屬性可能不會改變堆棧跟蹤的第一行(比如當(dāng) error.stack 在該屬性被改變之前被讀取)。
demo:
try{ const a = 1 + b; }catch(err){ console.log(err.message); } // b is not defined
說明:
error.stack 屬性是一個字符串,描述代碼中 Error 被實例化的位置。
第一行會被格式化為 : ,
且?guī)弦幌盗袟恳恍卸家?“at ” 開頭)。 每一幀描述了一個代碼中導(dǎo)致錯誤生成的調(diào)用點。
V8 引擎會試圖顯示每個函數(shù)的名稱(變量名、函數(shù)名、或?qū)ο蟮姆椒?,但偶爾也可能找不到一個合適的名稱。
如果 V8 引擎沒法確定一個函數(shù)的名稱,則只顯示幀的位置信息。 否則,在位置信息的旁邊會顯示明確的函數(shù)名。
注意,幀只由 JavaScript 函數(shù)產(chǎn)生。
demo:
try{ const a = 1 + b; }catch(err){ console.log(err.stack); } // ReferenceError: b is not defined // at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:2:16) // at Module._compile (module.js:660:30) // at Object.Module._extensions..js (module.js:671:10) // at Module.load (module.js:573:32) // at tryModuleLoad (module.js:513:12) // at Function.Module._load (module.js:505:3) // at Function.Module.runMain (module.js:701:10) // at startup (bootstrap_node.js:193:16) // at bootstrap_node.js:617:3
說明:
Error 的子類,表示斷言失敗。 這種錯誤通常表示實際值和預(yù)期值不相等。
demo:
const assert = require('assert'); assert.strictEqual(1, 2); // AssertionError [ERR_ASSERTION]: 1 === 2
RangeError 類
說明:
Error 的一個子類,表明一個函數(shù)的一個給定的參數(shù)的值不在可接受的集合或范圍內(nèi);
無論是一個數(shù)字范圍還是給定函數(shù)參數(shù)的選項的集合。
demo:
require('net').connect(-1); // RangeError [ERR_SOCKET_BAD_PORT]: Port should be > 0 and < 65536. Received -1.
說明:
Error 的一個子類,表明試圖訪問一個未定義的變量。 這些錯誤通常表明代碼有拼寫錯誤或程序已損壞。
雖然客戶端代碼可能產(chǎn)生和傳播這些錯誤,但在實踐中,只有 V8 引擎會這么做。
demo:
console.log( a ); // ReferenceError: a is not defined
SyntaxError 類
說明:
Error 的一個子類,表明程序不是有效的 JavaScript 代碼。 這些錯誤是代碼執(zhí)行的結(jié)果產(chǎn)生和傳播的。
代碼執(zhí)行可能產(chǎn)生自 eval、Function、require 或 vm。 這些錯誤幾乎都表明程序已損壞。
demo:
eval('**'); // SyntaxError: Unexpected token **
說明:
Error 的一個子類,表明提供的參數(shù)不是一個被允許的類型。
例如,將一個函數(shù)傳給一個期望字符串的參數(shù)會被視為一個 TypeError。
demo:
require('url').parse(() => { }); // TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type function
說明:
系統(tǒng)錯誤是當(dāng)程序運行環(huán)境中發(fā)生異常時產(chǎn)生的。
有單獨的異常類,并且有單獨的屬性:
error.code屬性是一個表示錯誤碼的字符串,總是 E 帶上一串大寫字母。
error.errno屬性是一個數(shù)值或字符串。 如果返回一個數(shù)值,則數(shù)值是一個負(fù)數(shù),
對應(yīng) libuv 錯誤處理 中定義的錯誤碼。 如果返回一個字符串,則同 error.code。
error.syscall屬性是一個字符串,描述失敗的 系統(tǒng)調(diào)用。
error.path屬性是一個字符串,包含了相關(guān)不可用路徑名。
error.address屬性是對鏈接失敗的地址的描述。
error.port是一個鏈接端口不可用的端口值
說明:
JavaScript 異常是一個作為一個無效操作的結(jié)果或作為一個 throw 聲明的目標(biāo)所拋出的值。
雖然它不要求這些值是 Error 的實例或繼承自 Error 的類的實例,
但所有通過 Node.js 或 JavaScript 運行時拋出的異常都是 Error 實例。
有些異常在 JavaScript 層是無法恢復(fù)的。 這些異??倳?Node.js 進(jìn)程的崩潰。
例如 assert() 檢測或在 C++ 層調(diào)用的 abort()。
說明:
系統(tǒng)錯誤是當(dāng)程序運行環(huán)境中發(fā)生異常時產(chǎn)生的。
特別是,當(dāng)應(yīng)用程序違反了操作系統(tǒng)的限制時發(fā)生的操作錯誤,例如試圖讀取一個不存在的文件或用戶沒有足夠的權(quán)限。
系統(tǒng)錯誤通常產(chǎn)生于系統(tǒng)調(diào)用層級。
在大多數(shù) Unix 系統(tǒng)上,可通過運行 man 2 intro、man 3 errno、或在線文檔獲取錯誤代碼的詳細(xì)清單和含義。
系統(tǒng)錯誤是由擴展的 Error 對象加上附加屬性表現(xiàn)的。
常見的系統(tǒng)錯誤:
以下列表是不完整的,但列舉了編寫 Node.js 程序時會遇到的一些常見的系統(tǒng)錯誤。 詳細(xì)的列表可從 ERRNO 文檔找到。
EACCES (拒絕訪問): 試圖以被一個文件的訪問權(quán)限禁止的方式訪問一個文件。EADDRINUSE (地址已被使用): 試圖綁定一個服務(wù)器(net、http 或 https)到本地地址,但因另一個本地系統(tǒng)的服務(wù)器已占用了該地址而導(dǎo)致失敗。
ECONNREFUSED (連接被拒絕): 無法連接,因為目標(biāo)機器積極拒絕。 這通常是因為試圖連接到外部主機上的廢棄的服務(wù)。
ECONNRESET (連接被重置): 一個連接被強行關(guān)閉。 這通常是因為連接到遠(yuǎn)程 socket 超時或重啟。 常發(fā)生于 http 和 net 模塊。
EEXIST (文件已存在): 一個操作的目標(biāo)文件已存在,而要求目標(biāo)不存在。
EISDIR (是一個目錄): 一個操作要求一個文件,但給定的路徑是一個目錄。
EMFILE (系統(tǒng)打開了太多文件): 已達(dá)到系統(tǒng)文件描述符允許的最大數(shù)量,且描述符的請求不能被滿足直到至少關(guān)閉其中一個。 當(dāng)一次并行打開多個文件時會發(fā)生這個錯誤,尤其是在進(jìn)程的文件描述限制數(shù)量較低的操作系統(tǒng)(如 macOS)。 要解決這個限制,可在運行 Node.js 進(jìn)程的同一 shell 中運行 ulimit -n 2048。
ENOENT (無此文件或目錄): 通常是由 fs 操作引起的,表明指定的路徑不存在,即給定的路徑找不到文件或目錄。
ENOTDIR (不是一個目錄): 給定的路徑雖然存在,但不是一個目錄。 通常是由 fs.readdir 引起的。
ENOTEMPTY (目錄非空): 一個操作的目標(biāo)是一個非空的目錄,而要求的是一個空目錄。 通常是由 fs.unlink 引起的。
EPERM (操作不被允許): 試圖執(zhí)行一個需要更高權(quán)限的操作。
EPIPE (管道損壞): 寫入一個管道、socket 或 FIFO 時沒有進(jìn)程讀取數(shù)據(jù)。 常見于 net 和 http 層,表明遠(yuǎn)端要寫入的流已被關(guān)閉。
ETIMEDOUT (操作超時): 一個連接或發(fā)送的請求失敗,因為連接方在一段時間后沒有做出合適的響應(yīng)。 常見于 http 或 net。 往往標(biāo)志著 socket.end() 沒有被正確地調(diào)用
以上就是關(guān)于Node.js API中如何使用Error模塊的內(nèi)容,如果你們有學(xué)習(xí)到知識或者技能,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。