Відтворення проблеми
У мене виникають проблеми при спробі передавати повідомлення про помилки за допомогою веб-розеток. Я можу повторити проблему, з якою я стикаюся, JSON.stringify
щоб задовольнити широку аудиторію:
// 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);
'{}'
Проблема в тому, що я закінчую порожній об’єкт.
Що я спробував
Браузери
Я спершу спробував залишити node.js і запустити його в різних браузерах. Версія Chrome Chrome 28 дає такий же результат, і що цікаво, Firefox принаймні робить спробу, але повідомлення пропустив:
>>> JSON.stringify(error); // Firebug, Firefox 23
{"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}
Функція заміщення
Потім я подивився на Error.prototype . Це показує, що прототип містить методи, такі як toString і toSource . Знаючи, що функції не можна поширити, я включив функцію заміщення, коли дзвонив JSON.stringify, щоб видалити всі функції, але потім зрозумів, що він теж мав якесь дивне поведінку:
var error = new Error('simple error message');
JSON.stringify(error, function(key, value) {
console.log(key === ''); // true (?)
console.log(value === error); // true (?)
});
Він, здається, не перетинає об'єкт, як зазвичай, і тому я не можу перевірити, чи є ключ функцією, і проігнорувати його.
Питання
Чи є спосіб упорядкувати рідні повідомлення про помилки JSON.stringify
? Якщо ні, то чому така поведінка відбувається?
Методи подолання цього
- Дотримуйтесь простих рядкових повідомлень про помилки або створюйте особисті об’єкти помилок і не покладайтеся на нативний об'єкт Error.
- Витягніть властивості:
JSON.stringify({ message: error.message, stack: error.stack })
Оновлення
@Ray Toal Запропонував у коментарі, щоб я подивився на дескриптори властивості . Тепер зрозуміло, чому це не працює:
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);
}
Вихід:
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 }
Ключ: enumerable: false
.
Прийнята відповідь дає вирішення цієї проблеми.