2017-07-04 9 views
0

NodeJs Expressアプリケーションのエラー処理に関するコードアーキテクチャーに関する質問が増えています。私はエラー処理のための最良のパターンが何であるかはわかりません。そのメモでは、どのような状況をエラーとみなすべきですか。たとえば、不正な資格情報を送信するときにこの応答が予想されるにもかかわらず、401 Unauthorizedコードがエラーとみなされていますか?Express Error Handling Opinion&Best Practice

使用:

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

を私は一般的にデータベースが見つからないという状況やネットワーク接続の問題や機能障害を表すことになり、ここだけ入れた5xxエラーのために傾向があります。残りの部分については、res.status(xxx).send();などの種類のコードを明示的にコーディングして、コントローラから401などのステータスコードを手動で返信します。しかし、私がやっていることの背後にある問題は、自分自身を繰り返す傾向があり、ロギングをアプリ全体に散らばらせる必要があるということです。私のアプローチは良いですか?代わりに、異なる範囲のステータスコードに対して複数のエラー処理ミドルウェアを作成する必要がありますか?

答えて

0

私はこの問題に対処するためにカスタムエラークラスを使ってmiddlewareを使用することをお勧めします。

エラークラスを見てみましょう。このクラスには、カスタムエラーメッセージ、httpステータスコード、およびloggerを使用している場合の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 
    }