Repository: sindresorhus/serialize-error (js)

Issue:
v7 doesn't work as described
The breaking change in v7 turned the example from the `README.md` useless:

```
const {serializeError, deserializeError} = require('serialize-error');

const error = new Error('🦄');

console.log(error);
//=> [Error: 🦄]

const serialized = serializeError(error)

console.log(serialized);
//=> {name: 'Error', message: '🦄', stack: 'Error: 🦄\n    at Object.<anonymous> …'}

const deserialized = deserializeError(serialized);
//=> [Error: 🦄]
```

The serialized error looks just like an empty object now, and is missing the `name`, `message`, and `stack` properties on the console. Actually, for me this was the most useful feature, and hence v7 is a huge step into the wrong direction.

I understand that you wanted to change it this way to keep things consistent – however, is there a chance to make this configurable?

Pull request description:
Make serialized error properties enumerable
## Description

Closes #31

Make serialized error properties enumerable again.

@sindresorhus I made `destroyCircular` accept an object as parameter to avoid having a fourth parameter and let `to_` be optional. Hope you don't mind.

Patch:
diff --git a/index.js b/index.js
index 06a2916..508c6a2 100644
--- a/index.js
+++ b/index.js
@@ -30,7 +30,7 @@ const commonProperties = [
 	{property: 'code', enumerable: true}
 ];
 
-const destroyCircular = (from, seen, to_) => {
+const destroyCircular = ({from, seen, to_, forceEnumerable}) => {
 	const to = to_ || (Array.isArray(from) ? [] : {});
 
 	seen.push(from);
@@ -46,7 +46,7 @@ const destroyCircular = (from, seen, to_) => {
 		}
 
 		if (!seen.includes(from[key])) {
-			to[key] = destroyCircular(from[key], seen.slice());
+			to[key] = destroyCircular({from: from[key], seen: seen.slice(), forceEnumerable});
 			continue;
 		}
 
@@ -57,7 +57,7 @@ const destroyCircular = (from, seen, to_) => {
 		if (typeof from[property] === 'string') {
 			Object.defineProperty(to, property, {
 				value: from[property],
-				enumerable,
+				enumerable: forceEnumerable ? true : enumerable,
 				configurable: true,
 				writable: true
 			});
@@ -69,7 +69,7 @@ const destroyCircular = (from, seen, to_) => {
 
 const serializeError = value => {
 	if (typeof value === 'object' && value !== null) {
-		return destroyCircular(value, []);
+		return destroyCircular({from: value, seen: [], forceEnumerable: true});
 	}
 
 	// People sometimes throw things besides Error objects…
@@ -88,7 +88,7 @@ const deserializeError = value => {
 
 	if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
 		const newError = new Error();
-		destroyCircular(value, [], newError);
+		destroyCircular({from: value, seen: [], to_: newError});
 		return newError;
 	}
 


Test patch:
diff --git a/test.js b/test.js
index dd0e232..c906dfe 100644
--- a/test.js
+++ b/test.js
@@ -10,9 +10,11 @@ function deserializeNonError(t, value) {
 
 test('main', t => {
 	const serialized = serializeError(new Error('foo'));
-	t.true('name' in serialized);
-	t.true('stack' in serialized);
-	t.true('message' in serialized);
+	const properties = Object.keys(serialized);
+
+	t.true(properties.includes('name'));
+	t.true(properties.includes('stack'));
+	t.true(properties.includes('message'));
 });
 
 test('should destroy circular references', t => {
@@ -172,7 +174,7 @@ test('should deserialize plain object', t => {
 	t.is(deserialized.code, 'code');
 });
 
-test('name, stack and message should not be enumerable, other props should be', t => {
+test('deserialized name, stack and message should not be enumerable, other props should be', t => {
 	const object = {
 		message: 'error message',
 		stack: 'at <anonymous>:1:13',