Reproduire le problème
Je rencontre un problème lorsque j'essaie de transmettre des messages d'erreur concernant l'utilisation des sockets Web. Je peux reproduire le problème auquel je fais face JSON.stringify
pour répondre à un public plus large:
// node v0.10.15
> var error = new Error('simple error message');
undefined
> error
[Error: simple error message]
> Object.getOwnPropertyNames(error);
[ 'stack', 'arguments', 'type', 'message' ]
> JSON.stringify(error);
'{}'
Le problème est que je me retrouve avec un objet vide.
Ce que j'ai essayé
Navigateurs
J'ai d'abord essayé de quitter node.js et de l'exécuter dans divers navigateurs. La version 28 de Chrome me donne le même résultat et, chose intéressante, Firefox fait au moins une tentative mais laisse de côté le message:
>>> JSON.stringify(error); // Firebug, Firefox 23
{"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}
Fonction de remplacement
J'ai ensuite regardé le prototype Error.prototype . Il montre que le prototype contient des méthodes telles que toString et toSource . Sachant que les fonctions ne peuvent pas être stringifiées, j'ai inclus une fonction de remplacement lors de l'appel de JSON.stringify pour supprimer toutes les fonctions, mais ensuite réalisé qu'elle avait également un comportement étrange:
var error = new Error('simple error message');
JSON.stringify(error, function(key, value) {
console.log(key === ''); // true (?)
console.log(value === error); // true (?)
});
Il ne semble pas boucler sur l'objet comme il le ferait normalement, et donc je ne peux pas vérifier si la clé est une fonction et l'ignorer.
La question
Existe-t-il un moyen de filtrer les messages d'erreur natifs avec JSON.stringify
? Sinon, pourquoi ce problème se produit-il?
Méthodes pour contourner ce problème
- Restez avec des messages d'erreur simples basés sur des chaînes ou créez des objets d'erreur personnels et ne vous fiez pas à l'objet d'erreur natif.
- Propriétés de traction:
JSON.stringify({ message: error.message, stack: error.stack })
Mises à jour
@Ray Toal Suggéré dans un commentaire que je regarde les descripteurs de propriété . Il est maintenant clair pourquoi cela ne fonctionne pas:
var error = new Error('simple error message');
var propertyNames = Object.getOwnPropertyNames(error);
var descriptor;
for (var property, i = 0, len = propertyNames.length; i < len; ++i) {
property = propertyNames[i];
descriptor = Object.getOwnPropertyDescriptor(error, property);
console.log(property, descriptor);
}
Production:
stack { get: [Function],
set: [Function],
enumerable: false,
configurable: true }
arguments { value: undefined,
writable: true,
enumerable: false,
configurable: true }
type { value: undefined,
writable: true,
enumerable: false,
configurable: true }
message { value: 'simple error message',
writable: true,
enumerable: false,
configurable: true }
Key: enumerable: false
.
La réponse acceptée fournit une solution de contournement à ce problème.