LibJS: Implement Error.prototype.name setter (#1776)

The MDN example for creating a custom error type in javascript uses:

    function CustomError(foo, message, fileName, lineNumber) {
        var instance = new Error(message, fileName, lineNumber);
        instance.name = 'CustomError';
        instance.foo = foo;
        Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
        return instance;
    }

The name property on the Error prototype needs to be settable for
this to work properly.
This commit is contained in:
Brian Gianforcaro 2020-04-13 02:19:53 -07:00 committed by GitHub
parent 984c290ec0
commit 2a65db7c12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: sideshowbarker 2024-07-19 07:38:25 +09:00
4 changed files with 30 additions and 1 deletions

View file

@ -39,6 +39,8 @@ public:
const FlyString& name() const { return m_name; }
const String& message() const { return m_message; }
void set_name(const FlyString& name) { m_name = name; }
private:
virtual bool is_error() const final { return true; }
virtual const char* class_name() const override { return "Error"; }

View file

@ -36,7 +36,7 @@ namespace JS {
ErrorPrototype::ErrorPrototype()
{
put_native_property("name", name_getter, nullptr);
put_native_property("name", name_getter, name_setter);
put_native_property("message", message_getter, nullptr);
put_native_function("toString", to_string);
}
@ -55,6 +55,19 @@ Value ErrorPrototype::name_getter(Interpreter& interpreter)
return js_string(interpreter, static_cast<const Error*>(this_object)->name());
}
void ErrorPrototype::name_setter(Interpreter& interpreter, Value value)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
if (!this_object)
return;
if (!this_object->is_error()) {
interpreter.throw_exception<TypeError>("Not an Error object");
return;
}
auto name = FlyString(value.to_string());
static_cast<Error*>(this_object)->set_name(name);
}
Value ErrorPrototype::message_getter(Interpreter& interpreter)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());

View file

@ -41,6 +41,8 @@ private:
static Value to_string(Interpreter&);
static Value name_getter(Interpreter&);
static void name_setter(Interpreter&, Value);
static Value message_getter(Interpreter&);
};

View file

@ -0,0 +1,12 @@
try {
var changedInstance = new Error("");
changedInstance.name = 'NewCustomError';
assert(changedInstance.name === "NewCustomError");
var normalInstance = new Error("");
assert(normalInstance.name === "Error");
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e.message);
}