N'est-il pas possible de stringify une Erreur en utilisant JSON.stringify?

De reproduire le problème

Je suis en cours d'exécution dans un problème lorsque vous essayez de transmettre des messages d'erreur autour de l'utilisation des sockets web. Je peux reproduire le problème, je suis confronté à l'aide de 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 en cours d'exécution dans les différents navigateurs. La version Chrome 28 me donne le même résultat, et qui est assez intéressant, Firefox au moins fait une tentative, mais à gauche du message:

>>> JSON.stringify(error); //Firebug, Firefox 23
{"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}

Fonction Replacer

J'ai alors regardé les Erreur.prototype. Il montre que le prototype contient des méthodes telles que toString et toSource. Sachant que les fonctions ne peuvent pas être stringified, j'ai inclus une fonction replacer lors de l'appel de JSON.stringify pour supprimer toutes les fonctions, mais alors réalisé qu'il avait un étrange comportement:

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 en boucle sur l'objet comme il le ferait normalement, et donc je ne peux pas vérifier si la clé est une fonction et de l'ignorer.

La Question

Est-il possible de stringify natif des messages d'Erreur avec JSON.stringify? Si non, pourquoi ce comportement ne se produisent?

Méthodes de contourner ce

  • Bâton avec simple basé sur des chaînes de messages d'erreur, ou de créer des objets d'erreur et ne comptez pas sur l'objet Error natif.
  • Pull propriétés: JSON.stringify({ message: error.message, stack: error.stack })

Mises à jour

@Ray Toal Suggéré dans un commentaire que je prends un coup d'oeil à la propriété des descripteurs. Il est clair maintenant pourquoi il 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);
}

De sortie:

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 }

Clés: enumerable: false.

Accepté de répondre fournit une solution de contournement pour ce problème.

  • Avez-vous examiné la propriété des descripteurs pour les propriétés de l'objet d'erreur?
  • La question pour moi était "pourquoi", et j'ai trouvé la réponse se trouvait au fond de la question. Il n'y a rien de mal à poster une réponse à votre propre question, et vous obtiendrez probablement plus de cred de cette façon. 🙂