title: Is it not possible to stringify an Error using JSON.stringify?
body: <h2>Reproducing the problem</h2>
  
  <p>I'm running into an issue when trying to pass error messages around using web sockets. I can replicate the issue I am facing using <code>JSON.stringify</code> to cater to a wider audience:</p>
  
  <pre class="lang-js prettyprint-override"><code>// node v0.10.15
  &gt; var error = new Error('simple error message');
      undefined
  
  &gt; error
      [Error: simple error message]
  
  &gt; Object.getOwnPropertyNames(error);
      [ 'stack', 'arguments', 'type', 'message' ]
  
  &gt; JSON.stringify(error);
      '{}'
  </code></pre>
  
  <p>The problem is that I end up with an empty object.</p>
  
  <h2>What I've tried</h2>
  
  <p><strong>Browsers</strong></p>
  
  <p>I first tried leaving node.js and running it in various browsers. Chrome version 28 gives me the same result, and interestingly enough, Firefox at least makes an attempt but left out the message:</p>
  
  <pre class="lang-js prettyprint-override"><code>&gt;&gt;&gt; JSON.stringify(error); // Firebug, Firefox 23
  {"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}
  </code></pre>
  
  <p><strong>Replacer function</strong></p>
  
  <p>I then looked at the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/prototype?redirectlocale=en-US&amp;redirectslug=JavaScript/Reference/Global_Objects/Error/prototype" rel="noreferrer">Error.prototype</a>. It shows that the prototype contains methods such as <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString?redirectlocale=en-US&amp;redirectslug=JavaScript/Reference/Global_Objects/Error/toString" rel="noreferrer">toString</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toSource?redirectlocale=en-US&amp;redirectslug=JavaScript/Reference/Global_Objects/Error/toSource" rel="noreferrer">toSource</a>. Knowing that functions can't be stringified, I included a <a href="https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_parameter" rel="noreferrer">replacer function</a> when calling JSON.stringify to remove all functions, but then realized that it too had some weird behavior:</p>
  
  <pre class="lang-js prettyprint-override"><code>var error = new Error('simple error message');
  JSON.stringify(error, function(key, value) {
      console.log(key === ''); // true (?)
      console.log(value === error); // true (?)
  });
  </code></pre>
  
  <p>It doesn't seem to loop over the object as it normally would, and therefore I can't check if the key is a function and ignore it.</p>
  
  <h2>The Question</h2>
  
  <p>Is there any way to stringify native Error messages with <code>JSON.stringify</code>? If not, why does this behavior occur?</p>
  
  <h3>Methods of getting around this</h3>
  
  <ul>
  <li>Stick with simple string-based error messages, or create personal error objects and don't rely on the native Error object.</li>
  <li>Pull properties: <code>JSON.stringify({ message: error.message, stack: error.stack })</code></li>
  </ul>
  
  <h3>Updates</h3>
  
  <p><a href="https://stackoverflow.com/users/831878/ray-toal">@Ray Toal</a> Suggested in a comment that I take a look at the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor?redirectlocale=en-US&amp;redirectslug=JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor" rel="noreferrer">property descriptors</a>. It is clear now why it does not work:</p>
  
  <pre class="lang-js prettyprint-override"><code>var error = new Error('simple error message');
  var propertyNames = Object.getOwnPropertyNames(error);
  var descriptor;
  for (var property, i = 0, len = propertyNames.length; i &lt; len; ++i) {
      property = propertyNames[i];
      descriptor = Object.getOwnPropertyDescriptor(error, property);
      console.log(property, descriptor);
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre class="lang-js prettyprint-override"><code>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 }
  </code></pre>
  
  <p>Key: <code>enumerable: false</code>.</p>
  
  <p>Accepted answer provides a workaround for this problem.</p>