2017-07-04 3 views
0

Ich habe mehr von einer Code-Architektur-Frage zur Fehlerbehandlung NodeJs Express-Anwendungen. Ich bin nicht sicher, was das beste Muster für die Fehlerbehandlung ist. In diesem Sinne sollten die Situationen als Fehler betrachtet werden. Wird ein 401 Unauthorized-Code beispielsweise als Fehler betrachtet, obwohl diese Antwort beim Senden von ungültigen Anmeldeinformationen erwartet wird?Express Fehlerbehandlung Meinung & Best Practice

Bei Verwendung:

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

Ich neige dazu, im Allgemeinen nur hier setzen 5xx Fehler, die Situationen, in denen eine Datenbank nicht oder keine Netzwerkverbindung Problem oder Funktionsstörungen darstellen würde. Für den Rest würde ich manuell einen Statuscode, wie zum Beispiel einen 401, von der Steuerung zurücksenden, indem ich explizit res.status(xxx).send(); oder etwas Ähnliches codiere. Aber das Problem hinter dem, was ich tue, ist, dass ich dazu tendiere, mich zu wiederholen und Logging über die App verstreut zu platzieren. Ist meine Vorgehensweise in Ordnung? Sollte ich stattdessen mehrere Fehlerbehandlungs-Middlewares für verschiedene Bereiche von Statuscodes erstellen? Ich brauche eine Option

Antwort

0

Ich bevorzuge mit middleware mit Ihrer benutzerdefinierten Fehlerklasse, um mit diesem Problem umzugehen.

Lassen Sie uns eine Fehlerklasse sehen, die eine benutzerdefinierte Fehlermeldung, HTTP-Statuscode und logLevel enthält, wenn Sie Logger verwenden.

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 
    } 
    } 
}; 

Nun schauen wir uns einen Controller an. Wir haben nur eine erfolgreiche Antwort von diesem Controller gesendet und benutzerdefinierte Fehler an Middleware übergeben.

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) 
     } 
    } 

Werfen wir nun einen Blick auf Logger und Fehlerhandler Middlewares. Hier protokolliert der Logger die Fehler in api und übergibt den Fehler an die Fehlerbehandlungsroutinen. Diese Funktionen würden dann in app.use() verwendet werden.

// 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 
    }