2016-07-21 8 views
5

Vorwort:Warum sind meine JS-Versprechen Fehlerobjekte leer?

  • Mungo Verwendung
  • Drossel Verwendung und mpromise Innenseite Mungo ersetzt
  • Die req.helpers.consoleMessage Funktion unten gesehen in ihm eine Funktion mit einigen einfachen Logik ist, dass, wenn sie nicht angezeigt werden bestimmt, eine bestimmte Detaillierungsstufe, die auf dem Vorhandensein von Debugging basiert, das in der App-Konfiguration aktiviert wurde, UND dem Nicht-Null-/Undefiniert-Status der Objekte, die angezeigt werden. Die gesamten Nachrichten werden mit JSON beschriftet und zurückgegeben, um auf der Konsole angezeigt zu werden.

Code:

Hier ist ein Beispiel von Code diese Symptome zeigt.

Dies ist eine delete Route für die :team:comment Einheiten in einer API, ich arbeite an. Ich habe absichtlich die Linie var response = user.comments; mit einem Fehler in Bezug auf ein user Objekt verlassen, wenn es eigentlich team sein sollte, die von der aufrufenden Funktion zurückgegeben und in das Versprechen übergeben werden sollte. Dies sollte einen Referenzfehler verursachen, da der Benutzer nicht definiert ist.

var console = clim("(DELETE /api/v1/team/:team/comments/:comment):", logger); 

    // create a filters request for mongoose 
    var query = {}; 

    // determine if the :team param is a username or an object id 
    req.helpers.validateObjectId(req.db, req.params.team) ? query._id = req.params.team : query.name = req.params.team; 

    if(req.helpers.validateObjectId(req.db, req.params.comment)) { 

     // looks good; create an update object 
     var update = { $pull: { comments: { _id: req.params.comment } } }; 

     // find the comment using the query above and pull the comment id 
     req.models.Team.findOneAndUpdate(
      query, 
      update, 
      {safe: true, new : true} 
     ).then(function(team){ 

      if(!team){ 

       // create the response object 
       var response = { 
        success: false, 
        message: "Team not found" 
       }; 

       // log request 
       console.info(req.helpers.consoleMessage(req, response, null)); 

       // respond with an appropriate array 
       res.status(404).json(response); 

      }else{ 

       // create the response object using the teams's comments 
       var response = user.comments; 

       // log request 
       console.info(req.helpers.consoleMessage(req, response, null)); 

       // respond with the team comments array 
       res.status(200).json(response); 

      } 

     }).then(null, function(err){ 

      // create the response 
      var response = { success: false, message: req.config.debug ? err: "An error has occur with your request; please try again" }; 

      // log the errors 
      console.error(req.helpers.consoleMessage(req, response, err)); 

      // or send a 500 internal server error 
      res.status(500).json(response); 

     }); 

    }else{ 

     // create the response 
     var response = { success: false, message: "Comment id is not a valid object id" }; 

     // log the errors 
     console.info(req.helpers.consoleMessage(req, response, null)); 

     // or send a 500 internal server error 
     res.status(500).json(response); 

    } 

Symptom:

diese Route aufrufen wird einen Fehler erzeugen und zu bewirken, dass der .catch() in einem Versuch, Feuer aus dem fehlerbehafteten Zustand wiederherzustellen jedoch das err Objekt scheint leer zu sein.

Ex. HTTP-Antwort: { success: false, message: {} }

Ex. Konsole log (abgekürzt aus Gründen der Klarheit) { req: {...}, res: {...}. err: {} }

Fazit:

err Das Objekt erscheint leer zu sein ...

Antwort

8

Problem:

Protokollieren des Fehlerobjekt für sich allein auf die Konsole wird zeigen, dass das Objekt tatsächlich nicht leer ist und Eigenschaften wie err.message ist sehr machbar.

Das Problem ist, dass JS-Fehler Objekt nicht naiv mit JSON beschriftet werden kann. Dies - zusammen mit Möglichkeiten, um mit diesem Problem umzugehen - sind ausführlich in der zugehörigen SOF-Frage beschrieben: Is it not possible to stringify an Error using JSON.stringify?.

Aktualisiert Code:

Die folgenden Code-Änderungen vorgenommen wurden, die Nachricht zu spezifizieren, in der HTTP-Antwort und die Hilfsfunktion (zuvor beschrieben) wurde aktualisiert, um spezifische Details des Fehlers angezeigt werden gezeigt : Ex: { err: { message: err.message, stack: err.stack } } und so weiter.

var console = clim("(DELETE /api/v1/team/:team/comments/:comment):", logger); 

    // create a filters request for mongoose 
    var query = {}; 

    // determine if the :team param is a username or an object id 
    req.helpers.validateObjectId(req.db, req.params.team) ? query._id = req.params.team : query.name = req.params.team; 

    if(req.helpers.validateObjectId(req.db, req.params.comment)) { 

     // looks good; create an update object 
     var update = { $pull: { comments: { _id: req.params.comment } } }; 

     // find the comment using the query above and pull the comment id 
     req.models.Team.findOneAndUpdate(
      query, 
      update, 
      {safe: true, new : true} 
     ).then(function(team){ 

      if(!team){ 

       // create the response object 
       var response = { 
        success: false, 
        message: "Team not found" 
       }; 

       // log request 
       console.info(req.helpers.consoleMessage(req, response, null)); 

       // respond with an appropriate array 
       res.status(404).json(response); 

      }else{ 

       // create the response object using the teams's comments 
       var response = team.comments; 

       // log request 
       console.info(req.helpers.consoleMessage(req, response, null)); 

       // respond with the team comments array 
       res.status(200).json(response); 

      } 

     }).then(null, function(err){ 

      // create the response 
      var response = { success: false, message: req.config.debug ? err.message : "An error has occur with your request; please try again" }; 

      // log the errors 
      console.error(req.helpers.consoleMessage(req, response, err)); 

      // or send a 500 internal server error 
      res.status(500).json(response); 

     }); 

    }else{ 

     // create the response 
     var response = { success: false, message: "Comment id is not a valid object id" }; 

     // log the errors 
     console.info(req.helpers.consoleMessage(req, response, null)); 

     // or send a 500 internal server error 
     res.status(500).json(response); 

    } 

Warum teile ich solch ein einfaches Konzept?

ich stundenlang gesucht versuchen, herauszufinden, was ich falsch mit meinen Versprechen Kettenstrukturen zu tun und verwendet, um die Schlüsselwort empty und error (zusammen mit jeder Kombination von Worten in Bezug auf JS Promises), aber keiner meiner Suche kam mit etwas nach oben nützlich, außer zu bestätigen, dass ich mich dem richtig näherte. Alles schien mit meinem Hilfsskript in Ordnung zu sein und ich konnte anscheinend nicht die richtigen Debugging-Schritte ausführen, um herauszufinden, wo das Problem lag, bis ich das err Objekt direkt in die Konsole ausgegeben habe (warum sollte ich das tun müssen) ? Ich war schon ... oder so dachte ich).

Also könnte man sagen, dass ich versuche einige Leute zu retten, für den Fall, dass jemand in eine ähnliche Situation gerät und denkt: "Warum funktionieren meine Versprechungen nicht so wie geplant?" und, wie ich, zufällig in der falschen Richtung suchen.

Happy Coding!

+0

Cool! Danke für Anteil. – danilodeveloper

+2

Hah, ich habe genau den gleichen Fehler gemacht. Dies ist die nützlichste Sache bei Stack Overflow heute für mich. Vielen Dank. – jlegler