Préface:
req.helpers.consoleMessage
Vue ci-dessous est une fonction avec une logique simple qui détermine quand afficher ou non un certain niveau de détail en fonction de l'existant de débogage activé dans la configuration de l'application ET du non-null/état indéfini des objets affichés. L'ensemble des messages est stratifié à l'aide de JSON
et renvoyé pour être affiché sur la console.Code:
Voici un exemple de code montrant ces symptômes.
Il s'agit d'une route delete
pour les unités :team
:comment
Dans une API sur laquelle je travaille. J'ai intentionnellement laissé la ligne var response = user.comments;
Avec une erreur faisant référence à un objet user
alors qu'en fait il devrait être team
qui devrait être retourné par la fonction appelante et passé dans la fonction Promise.then()
. Cela devrait provoquer une erreur de référence car l'utilisateur n'est pas défini.
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);
}
Symptôme:
L'appel de cette route produira une erreur et provoquera la .catch()
à déclencher dans une tentative de récupération de l'état erroné, cependant l'objet err
semble être vide.
Ex. Réponse HTTP: { success: false, message: {} }
Ex. Journal de la console (abrégé pour plus de clarté) { req: {...}, res: {...}. err: {} }
Conclusion:
L'objet err
semble vide ...
Problème:
La journalisation de l'objet d'erreur sur la console par elle-même révélera que l'objet n'est en effet pas vide et que les propriétés de capture telles que err.message
est très faisable.
Le problème est que l'objet d'erreur JS ne peut pas être naïvement stratifié à l'aide de JSON
. Ceci - ainsi que les moyens de résoudre ce problème - sont décrits en détail dans la question SOF associée: N'est-il pas possible de filtrer une erreur en utilisant JSON.stringify? .
Code mis à jour:
Les modifications de code suivantes ont été apportées pour spécifier le message à afficher dans la réponse HTTP et la fonction d'assistance (décrite précédemment) a été mise à jour pour spécifier les détails de l'erreur à afficher: Ex: { err: { message: err.message, stack: err.stack } }
etc.
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);
}
Pourquoi est-ce que je partage un concept aussi simple?
J'ai cherché pendant des heures à essayer de comprendre ce que je faisais incorrectement avec mes structures de chaîne de promesses et j'ai utilisé les mots clés empty
et error
(ainsi que toutes les combinaisons de mots concernant JS Promises), mais aucun de mes les recherches ont trouvé quelque chose d'utile autre que de confirmer que j'approchais cela correctement. Tout semblait bien se passer avec mon script d'aide et je n'arrivais pas à faire les bonnes étapes de débogage pour comprendre où était le problème jusqu'à ce que j'arrive en essayant de sortir l'objet err
directement dans la console (pourquoi Je dois faire ça? Je l'étais déjà ... ou du moins je le pensais).
Donc je suppose que vous pourriez dire que j'essaie de faire gagner du temps à certaines personnes au cas où quelqu'un se retrouverait dans une situation similaire et se demanderait "pourquoi mes promesses ne fonctionnent-elles pas comme prévu!" et, comme moi, cherche dans la mauvaise direction.
Codage heureux!