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