I tried to extend the JavaScript error properties through the extension of the prototype of the Error constructor:
<script type="text/javascript">// extending the Error properties to all the ones available in the various browsers:Error.prototype = { name: null, // (all browsers); the name of the error message: null, // (all browsers); the error message as a string description: null, // (Internet Explorer); description of the error fileName: null, // (Firefox); the name of the file where the error occurred lineNumber: null, // (Firefox); the number of line where the error occurred columnNumber: null, // (Firefox); the number of column where the error occurred number: null, // (Internet Explorer); the error code as a number stack: null // (Firefox, Chrome); detailed information about the location where the error exactly occurred};function log(error) { var errors = []; for (var prop in error) { errors.push(prop + ': ' + error[prop]); } alert(errors.join('\n'));}</script>Then I test the log function:
<script type="text/javascript>try { var a = b; // b is undefined!} catch(error) { log(error);}</script>The result is that the error object only shows some properties (e.g. on FirefoxfileName,lineNumber andcolumnNumber) like if it has not been extended.
But the most strange thing is that thefor...in cycle seemsunable to walk all the error object properties: trying to alert the standard propertyerror.message normally returns a message.
So the results of my test are:
- the Error constructor is not extensible through its prototype, as other native constructors are;
- the
for...inloop is not able to walk the properties of an error object.
Am I right?
Are there some interesting evidences/resources you may suggest to know more about it?
- 1
Erroris a host object and therefore does not have to behave like "normal" JavaScript objects.Felix Kling– Felix Kling2013-01-14 11:26:15 +00:00CommentedJan 14, 2013 at 11:26 - Mmh, interesting, I did not know about host objects. I am learning through something about through Stackoverflow threads. As for now, I understood they are special objects with special properties and behaviours, such as DOM objects, am I right?yodabar– yodabar2013-01-14 11:36:42 +00:00CommentedJan 14, 2013 at 11:36
- 3Seees5.github.com/#x4.3.8. If you search for
host objecton this site you'll find some interesting statements about them.edit: They are basically objects supplied the environment and not part of the specification (just like DOM objects, yes). But the problem is probably just thatError.prototypeis not writable (at least in Firefox).var obj = {foo: 'bar'}; Error.prototype = obj; Error.prototype == obj;results infalse.Felix Kling– Felix Kling2013-01-14 11:39:26 +00:00CommentedJan 14, 2013 at 11:39 - 1Even non host objects may have non enumerable properties, btw.Denys Séguret– Denys Séguret2013-01-14 11:39:40 +00:00CommentedJan 14, 2013 at 11:39
- 2@Emanuele: You only have control over propertiesyou create.Felix Kling– Felix Kling2013-01-14 13:25:03 +00:00CommentedJan 14, 2013 at 13:25
1 Answer1
A. Like, Raynos said, The reasonmessage isn't being set is thatError is a function that returns a new Error object and doesnot manipulatethis in any way.
B. The way to do this right is to return the result of the apply from the constructor, as well as setting the prototype in the usual complicated javascripty way:
function MyError() { var tmp = Error.apply(this, arguments); tmp.name = this.name = 'MyError' this.stack = tmp.stack this.message = tmp.message return this} var IntermediateInheritor = function() {} IntermediateInheritor.prototype = Error.prototype; MyError.prototype = new IntermediateInheritor()var myError = new MyError("message");console.log("The message is: '"+myError.message+"'") // The message is: 'message'console.log(myError instanceof Error) // trueconsole.log(myError instanceof MyError) // trueconsole.log(myError.toString()) // MyError: messageconsole.log(myError.stack) // MyError: message \n // <stack trace ...>The only problems with this way of doing it at this point (i've iteratted it a bit) are that
- properties other than
stackandmessagearen't included inMyErrorand - the stacktrace has an additional line that isn't really necessary.
The first problem could be fixed by iterating through all the non-enumerable properties of error using the trick in this answer:Is it possible to get the non-enumerable inherited property names of an object?, but this isn't supported by ie<9. The second problem could be solved by tearing out that line in the stack trace, but I'm not sure how to safely do that (maybe just removing the second line of e.stack.toString() ??).
Comments
Explore related questions
See similar questions with these tags.
