2017-07-04 77 views
0

我有更多關於錯誤處理NodeJs Express應用程序的代碼體系結構問題。我不確定什麼是錯誤處理的最佳模式。在那張紙上,什麼樣的情況應該被視爲錯誤。例如,即使在發送錯誤憑證時預期會出現此響應,401 401未經授權的代碼也會被視爲錯誤?表達錯誤處理意見和最佳實踐

使用:

//app.js file 
app.use(err, req, res, next){} 

我一般傾向於在這裏只把5XX錯誤,這將是在一個數據庫中無法找到的情況下或沒有網絡連接問題或功能失效。至於其他方面,我會通過明確編碼res.status(xxx).send();或其他類似手段從控制器手動發送狀態代碼(如401)。但是我所做的背後的問題是我傾向於重複自己,並且必須將日誌散佈在應用程序中。我的方法很好嗎?我應該爲不同的狀態代碼範圍創建多個錯誤處理中間件嗎?我需要一個opnion

回答

0

我更喜歡使用middleware與您的自定義錯誤類來處理此問題。

讓我們來看看一個錯誤類,它包含一個自定義錯誤消息,http狀態碼和logLevel(如果您使用記錄器)。

module.exports = class ApiCalError extends Error { 
    constructor (message, status, logLevel) { 

    // Calling parent constructor of base Error class. 
    super(message); 

    // Capturing stack trace, excluding constructor call from it. 
    Error.captureStackTrace(this, this.constructor); 

    // Saving class name in the property of our custom error as a shortcut. 
    this.name = this.constructor.name; 

    // You can use any additional properties you want. 
    // I'm going to use preferred HTTP status for this error types. 
    // `500` is the default value if not specified. 
    this.status = status || 400; 

    this.logLevel = logLevel || 'warn'; 

    } 

    toResponseJSON() { 
    return { 
     success: false, 
     message: this.message 
    } 
    } 
}; 

現在,讓我們看看一個控制器。我們只從這個控制器發送了成功的響應,並將自定義錯誤傳遞給了中間件。

exports.Login = function(req, res, next) { 
     const validationResult = validateLoginForm(req.body) 
     if (!validationResult.success) { 
      var err = new customError(validationResult.message, 400, 'warn') 
      return next(err) 
     } else { 
      return passport.authenticate('local-login', (err, token, userData) => { 
       if (err) { 
        if (err.name == 'IncorrectCredentialsError' || err.name == 'EmailNotVerified') { 
         var error = new customError(err.message, 400, 'warn') 
         return next(error) 
        } 
        return next(err) 
       } 
       return res.json({ 
        success: true, 
        message: 'You have successfully logged in!', 
        token, 
        user: userData 
       }) 
      })(req, res, next) 
     } 
    } 

現在,讓我們來看看記錄器和錯誤處理程序中間件。在這裏,記錄器將記錄api中的錯誤並將錯誤傳遞給錯誤處理程序。這些功能將在app.use()中使用。

// Import library 

    var Logger = function(logger) { 
     return function(err, req, res, next) { 
      var meta = { 
       path: req.originalUrl, 
       method: req.method, 
       'user-agent': req.headers['user-agent'], 
       origin: req.headers.origin 
      } 
      if (err instanceof customError) { 
       logger.log(err.logLevel, err.message, meta) 
       return next(err) 
      } else { 
       logger.log('error', err.message, meta) 
       return next(err) 
      } 
     } 
    } 
    var ErrorHandler = function() { 
     return function(err, req, res, next) { 
      if (err instanceof customError) { 
       return res.status(err.status).json(err.toResponseJSON()) 
      }else{ 
       return res.status(500).json({ 
        success: false, 
        message: err.message 
       }) 
      } 
     } 
    } 

    module.exports = { 
     Logger, 
     ErrorHandler 
    }