2016-07-21 10 views
5

Wstęp:Dlaczego moje obiekty błędu obietnicy JS są puste?

  • Korzystanie Mongoose
  • Korzystanie Bluebird i zastąpienie mpromise wewnątrz Mongoose
  • req.helpers.consoleMessage funkcja widać poniżej jest funkcją z jakąś prostą logikę w nim, który określa, kiedy należy, a nie w celu wyświetlenia pewien poziom szczegółowości w oparciu o istniejące debugowanie włączone w konfiguracji aplikacji ORAZ o stanie innym niż null/niezdefiniowany wyświetlanych obiektów. Całe komunikaty zostaną uszeregowane za pomocą JSON i zwrócone do wyświetlenia na konsoli.

Kod:

Oto przykład jakiegoś kodu wykazujące te objawy.

Jest to trasa delete dla jednostek :team:comment w interfejsie API, nad którym pracuję. Celowo opuściłem linię var response = user.comments; z błędem w odwołaniu do obiektu user, podczas gdy w rzeczywistości powinien on być team, który powinien zostać zwrócony przez funkcję wywołującą i przekazany do obietnicy .then(). Powinno to spowodować błąd odniesienia, ponieważ użytkownik nie jest zdefiniowany.

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

    } 

Objaw:

Wywołanie tej trasy będzie produkować błąd i powodować .catch() na ogień, starając się wyjść z błędami stanie jednak przedmiotem err wydaje się być pusty.

Przykł. Odpowiedź HTTP: { success: false, message: {} }

Przykł. dziennik Console (skrócone dla jasności) { req: {...}, res: {...}. err: {} }

Wniosek:

Przedmiotem err wydaje się być pusty ...

Odpowiedz

8

Problem:

Logowanie obiekt błędzie pocieszyć sam pokaże, że obiekt nie jest rzeczywiście pusty, a pobieranie takich właściwości, jak err.message, jest bardzo wykonalne.

Problem polega na tym, że obiekt błędu JS nie może zostać naiwnie zmodyfikowany za pomocą JSON. To - wraz ze sposobami radzenia sobie z tym problemem - są szczegółowo opisane w powiązanym pytaniu SOF: Is it not possible to stringify an Error using JSON.stringify?.

Zaktualizowany kod:

następujące zmiany kodu zostały wykonane w celu określenia wiadomość być pokazane w odpowiedzi HTTP i funkcji pomocnika (opisane wcześniej) został zaktualizowany do specyficzne szczegóły błędu, aby pokazać : Przykład: { err: { message: err.message, stack: err.stack } } i tak dalej.

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

    } 

Dlaczego dzielę się tak prostą koncepcją?

Szukałem godziny próbuje dowiedzieć się, co robię nieprawidłowo ze strukturami moich łańcuchowych obietnica i używane słowa kluczowe empty i error (wraz z każdej kombinacji słów dotyczących Promises JS), ale żaden z moich poszukiwań wymyślił niczego przydatne, inne niż potwierdzenie, że podchodziłem do tego poprawnie. Wszystko wyglądało dobrze z moim skryptem pomocniczym i nie mogłem wydawać się, aby wykonać odpowiednie kroki debugowania, aby dowiedzieć się, gdzie jest problem, aż do momentu, w którym próbowałem wypuścić obiekt err bezpośrednio do konsoli (dlaczego musiałbym to zrobić? "Już byłem ... albo tak mi się wydawało).

Sądzę, że można powiedzieć, że próbuję uratować niektórych ludzi na wypadek, gdyby ktoś znalazł się w podobnej sytuacji i zastanawia się "dlaczego moje obietnice nie działają zgodnie z przeznaczeniem!" i podobnie jak ja, szukają w niewłaściwym kierunku.

Happy Coding!

+0

Cool! Dziękuję za udział. – danilodeveloper

+2

Hah, popełniłem dokładnie ten sam błąd. To jest najbardziej przydatna rzecz na dzisiejszym przepełnieniu stosu. Dzięki. – jlegler

Powiązane problemy