Created
February 27, 2014 19:13
-
-
Save nzakas/9257017 to your computer and use it in GitHub Desktop.
Is this a Node.js bug?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
value1: {"stack":"MyStack","type":"MyType"} true | |
value2: {"stack":"MyStack","message":"MyError"} true | |
value3: {"stack":"MyStack","message":"MyError"} true | |
value4: {"stack":"MyStack","type":"MyType"} true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
value1: {} false | |
value2: {"stack":"MyStack","message":"MyError"} true | |
value3: {"message":"MyError"} false | |
value4: {} false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Help me figure out if this is a bug in Node.js, V8, or someplace else. | |
* | |
* Situation: There's an object that inherits from Error via prototype chaining. | |
* We then overwrite stack and type (effectively shadowing the prototype properties) | |
* because they aren't enumerable by default and we want them to be. Doing this | |
* should create an enumerable stack and enumerable type on the new object. | |
* | |
* In Node.js, however, this is not the case. The properties seem to maintain their | |
* enumerability, and in fact, the properties don't get added to the new object. | |
* | |
* In Chrome, the properties are added as enumerable to the new object. | |
* | |
* I've included output from both Node.js and Chrome in this gist for reference. | |
*/ | |
var err = new Error('MyError'); | |
err.stack = 'MyStack'; | |
err.type = 'MyType'; | |
var value = {}; | |
for (var i in err) { | |
value[i] = err[i]; | |
} | |
console.log('value1:', JSON.stringify(value), value.hasOwnProperty('stack')); | |
value = {}; | |
value.stack = err.stack; | |
value.message = err.message; | |
console.log('value2:', JSON.stringify(value), value.hasOwnProperty('stack')); | |
value = Object.create(err); | |
value.stack = err.stack; | |
value.message = err.message; | |
console.log('value3:', JSON.stringify(value), value.hasOwnProperty('stack')); | |
value = Object.create(err); | |
for (var i in err) { | |
value[i] = err[i]; | |
} | |
console.log('value4:', JSON.stringify(value), value.hasOwnProperty('stack')); |
So it turns out that creating objects that violate [[Get]] what you [[Put]] cause really tricky non-intuitive situations.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Confirmed. Here's what happens in Chrome:
In Node 0.10, the second log statement outputs the same as the first. So it looks like the only real bug is a compatibility issue across browsers (Firefox implements
stack
as a data property only).