處理 Node.Js 中的異常

Node.js 有 3 種處理異常/錯誤的基本方法:

  1. try-catch
  2. error 作為 callback 的第一個引數
  3. emit 使用 eventEmitter 的錯誤事件

try-catch 用於捕獲從同步程式碼執行中丟擲的異常。如果呼叫者(或呼叫者的呼叫者,…)使用 try / catch,那麼他們可以捕獲錯誤。如果沒有任何呼叫者嘗試捕獲而不是程式崩潰。
如果在非同步操作上使用 try-catch,則非同步方法的回撥丟擲異常,而不會被 try-catch 捕獲。要從非同步操作回撥中捕獲異常,最好使用 promises
更好地理解它的例子

// ** Example - 1  **
function doSomeSynchronousOperation(req, res) {
    if(req.body.username === ''){
        throw new Error('User Name cannot be empty');
    }  
    return true;  
}

// calling the method above
try {
    // synchronous code   
    doSomeSynchronousOperation(req, res)    
catch(e) {
    //exception handled here   
    console.log(e.message);  
} 

// ** Example - 2 **
function doSomeAsynchronousOperation(req, res, cb) {
    // imitating async operation
    return setTimeout(function(){
        cb(null, []);
    },1000);
}
 
try {
    // asynchronous code   
    doSomeAsynchronousOperation(req, res, function(err, rs){
        throw new Error("async operation exception");
    })   
} catch(e) {
     // Exception will not get handled here
     console.log(e.message);  
}
// The exception is unhandled and hence will cause application to break

回撥主要在 Node.js 中使用,因為回撥是非同步傳遞事件的。使用者向你傳遞一個函式(回撥),並在非同步操作完成後稍後呼叫它。
通常的模式是回撥被呼叫為回撥(錯誤,結果) ,其中只有一個錯誤和結果是非空的,這取決於操作是成功還是失敗。

function doSomeAsynchronousOperation(req, res, callback) {
   setTimeout(function(){
        return callback(new Error('User Name cannot be empty'));    
   }, 1000);  
   return true;
}

doSomeAsynchronousOperation(req, res, function(err, result) {
   if (err) {
       //exception handled here 
       console.log(err.message);
   }
   
   //do some stuff with valid data
});

發出更復雜的情況,而不是使用回撥,函式本身可以返回一個 EventEmitter 物件,並且呼叫者應該監聽發射器上的錯誤事件。

const EventEmitter = require('events');

function doSomeAsynchronousOperation(req, res) {
    let myEvent = new EventEmitter();

    // runs asynchronously
    setTimeout(function(){
        myEvent.emit('error', new Error('User Name cannot be empty'));
    }, 1000);

    return myEvent;
}

// Invoke the function
let event = doSomeAsynchronousOperation(req, res);

event.on('error', function(err) {
    console.log(err);
});

event.on('done', function(result) {
    console.log(result); // true
});