Skip to content

Error object property "name" should be writable #144

Closed

Description

@lll000111

I give Error objects names (i.e. setting nameproperty, sometimes replacing an existing message property too) because I prefer this over sub-classing Errors, which only is simple on ES 2015 and with a functional style I don't have a single "class", "this", "bind" in any of my code, it's "just functions".

This is perfectly legal JS. It should just be a normal object.

Code

const e = new Error('test');
e.name = 'TestError';
trace(e.name + ' ' + e.message);

Result

Error: set name: not writable!

image

Activity

  1. lll000111 commented on Mar 10, 2019

    @lll000111
    Author

    It seems to me that this is due to xs/sources/xsError.c setting XS_GET_ONLY.

    I set this to XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG and then I could set a message in JS code.

    I also still cannot set the name property even though as far as I can see it only has XS_DONT_ENUM_FLAG set.


    EDIT: Am I confused? message apparently can be set, with or without the above change. It's only name that is not writable. I guess this comment is useless :-(
    Time to change the issue title...

    I can't see why a name property cannot be assigned to Error instances :(


    EDIT²: Now I'm really confused. In my project code message is not writable either, but it worked in the small example above.


    I think name is in the Error constructor's Prototype object. When I assign to an Error instance name property it should create a new property on the instance. Still, even the original name property on the prototype is writable, even if nobody should do that.

    From the ECMAscript standard

    Error instances are ordinary objects that inherit properties from the Error prototype object

    No write protection, no special object.

    MDN even has this example "Throwing a custom error":

    var e = new Error('Malformed input'); // e.name is 'Error'
    e.name = 'ParseError';
    throw e;
    // e.toString() would return 'ParseError: Malformed input'
  2. changed the title [-]Error objects should be writable[/-] [+]Error object property "name" should be writable[/+] on Mar 10, 2019
  3. lll000111 commented on Mar 11, 2019

    @lll000111
    Author
  4. phoddie commented on Mar 11, 2019

    @phoddie
    Collaborator

    This is a consequence of freezing of the Error.prototype during preload. You can read more about that here.

  5. lll000111 commented on Mar 11, 2019

    @lll000111
    Author

    I already know you are freezing prototypes. However, the way this works and is supposed to work, looking at other runtimes, is that a new property in the instance is created. If the measure you took prevent adding an instance property this is not just "freezing the prototype".

  6. lll000111 commented on Mar 11, 2019

    @lll000111
    Author

    I read the link again, I had already read it some time ago, just to be sure I did not misread.

    The example there explicitly directly changes the prototype object. This has nothing to do with this issue here. Assigning to name does not modify the prototype object in any way, it creates a new property directly on the instance object. The instance is in RAM and should be writable.

  7. phoddie commented on Mar 11, 2019

    @phoddie
    Collaborator

    It is a consequence of Error.prototype being frozen. The name property is on the prototype as per section 19.5.3.3 of the ECMAScript language specification. When an object is frozen, writes to existing properties fail, including those on instances that use the frozen prototype.

  8. lll000111 commented on Mar 11, 2019

    @lll000111
    Author

    Okay, they indeed do. TIL.

  9. lll000111 commented on Mar 11, 2019

    @lll000111
    Author

    Interesting that Object.defineProperty() still works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions