Closed Bug 181914 Opened 23 years ago Closed 23 years ago

Derived Error objects cannot call constructor

Categories

(Rhino Graveyard :: Core, defect)

defect
Not set
normal

Tracking

(Not tracked)

VERIFIED INVALID

People

(Reporter: joerg.schaible, Assigned: norrisboyd)

Details

(Whiteboard: Typo in Comment #2; see Comment #3)

Attachments

(4 files, 1 obsolete file)

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461) Build Identifier: Rhino 1.5 release 4 0000 00 00 (in progress) The description of ECMA 15.11 seem to imply that an Error object is a "normal" object and it should be possibly for an object of a dervied class to call its parent's constructor as usual. Unfortunately the message member will not be initialized as expected. See attached regression test. Reproducible: Always Steps to Reproduce: Run regression test with Rhino or SpiderMonkey. Actual Results: regression test fails. Expected Results: regression test succeeds. I am not really sure, if this is really an error. The ECMA description is not really clear about this case.
Regression test for this case.
cc'ing Waldemar on this one. Here is the heart of the testcase: // derive MyCallError from Error function MyCallError(msg) { Error.call(this, msg); } MyCallError.prototype = new Error(); MyCallError.prototype.name = "MyCallError"; var err = new MyCallError('msg'); Note |err.name| gets successfully set: js> err.name MyApplyError But |err.message| does not get set by |Error.call(this, msg)| inside the MyApplyError() constructor: js> err.message js> err.message === ''; true Jörg has provided a similar example using Error.apply: // derive MyApplyError from Error function MyApplyError(msg) { Error.apply(this, arguments); } MyApplyError.prototype = new Error(); MyApplyError.prototype.name = "MyApplyError"; var err = new MyApplyError('msg'); The behavior is the same as above: |err.name| is set (of course), but |err.message| does not get set inside the constructor. The behavior is the same in SpiderMonkey as in Rhino -
Typo in my comment above: > But |err.message| does not get set by |Error.call(this, msg)| > inside the MyApplyError() constructor: should be: > But |err.message| does not get set by |Error.call(this, msg)| > inside the MyCallError() constructor:
Whiteboard: Typo in Comment #2; see Comment #3
The behavior you see is as specified by ECMA. In 15.11.1, it states that the function call Error(...) is equivalent to the object creation expression new Error(...) with the same arguments. This means that it creates and returns a new Error object which has msg initialized properly. See section 13.2.2: the object creation expression creates and uses a new 'this' object. The code you have throws away that new object. To see this, change the function slightly: function MyCallError(msg) { z = Error.call(this, msg); } MyCallError.prototype = new Error(); MyCallError.prototype.name = "MyCallError"; var err = new MyCallError('msg'); Now evaluate z: js> z Error: msg js> z.message msg
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → INVALID
Marking Verified; thanks to all -
Status: RESOLVED → VERIFIED
Hello all, Hmmm. I am following quite exactly the User's Guide in Figure 8.6 (http://developer.netscape.com/docs/manuals/js/core/jsguide15/obj2.html#1008499) . While this is not the spec, the behaviour of the Error objects is somewhat unbalanced and surprising. I've added a patch for Rhino, that realizes the "expected behaviour". I have to admit though, that the description in the User's Guide is never guaranteed by the spec at all. Although the generated object of 13.2.2-1 is used for 13.2.1, the problem arises with 13.2.2-7, that allows the [[contructor]] to ignore the object from 13.2.2-1. That prevents any reliable call of a superclass' constructor.
Status: VERIFIED → REOPENED
Resolution: INVALID → ---
Showcase for Rhino
Updated regression test ensuring 15.11.1.1 for derived Error class.
Attachment #107393 - Attachment is obsolete: true
General regression test for 15.11.1.1
The ECMA spec is quite clear here, and both Rhino and Spidermonkey conform to the spec. The pattern mentioned in the user's guide in comment 6 applies to user-defined objects but doesn't apply to built-in objects, including Date, String, Number, Error, etc. That's an unfortunate defect/feature of the standard, but changing the standard would be a compatibility break and gratuitously break existing web pages.
Status: REOPENED → RESOLVED
Closed: 23 years ago23 years ago
Resolution: --- → INVALID
Marking Verified. I want to thank Waldemar for clarifying this issue, and Jörg for such precise questions. I have added Jörg's two testcases to the JS testsuite: mozilla/js/tests/ecma_3/Exceptions/15.11.1.1.js mozilla/js/tests/ecma_3/Exceptions/regress-181914.js For the latter, I simply changed the use of |Error| to |_Error|, a user-defined imitation of |Error|. This makes everything work.
Status: RESOLVED → VERIFIED
Hi Phil, the regress-181914.js was somewhat obsolete now, since it did not really test something new concerning Exception regress testing. I've attached a (last <g>) patch for this regression test, that modifies your user-defined _Error class to be a real Error object and add an eighth test case ensuring this. Test runs fine. Regards, Jörg
Jörg: good idea; I have checked in your improvements -
Targeting as resolved against 1.5R4
Target Milestone: --- → 1.5R4
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: