summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Gianforcaro <b.gianfo@gmail.com>2020-04-13 02:19:53 -0700
committerGitHub <noreply@github.com>2020-04-13 11:19:53 +0200
commit2a65db7c1253e4a070e8ac101faa2404dc7af99e (patch)
tree5110a338d908725df5e120e05e68275ea0f6e27e
parent984c290ec04806ba187e4789e2b63d5dfc26c1a4 (diff)
downloadserenity-2a65db7c1253e4a070e8ac101faa2404dc7af99e.zip
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.
-rw-r--r--Libraries/LibJS/Runtime/Error.h2
-rw-r--r--Libraries/LibJS/Runtime/ErrorPrototype.cpp15
-rw-r--r--Libraries/LibJS/Runtime/ErrorPrototype.h2
-rw-r--r--Libraries/LibJS/Tests/Error.prototype.name.js12
4 files changed, 30 insertions, 1 deletions
diff --git a/Libraries/LibJS/Runtime/Error.h b/Libraries/LibJS/Runtime/Error.h
index 76615b4b9e..ac15e7bbbd 100644
--- a/Libraries/LibJS/Runtime/Error.h
+++ b/Libraries/LibJS/Runtime/Error.h
@@ -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"; }
diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp
index 1e193a567b..0251fe779f 100644
--- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp
@@ -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());
diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.h b/Libraries/LibJS/Runtime/ErrorPrototype.h
index ffc13a8345..a851407fee 100644
--- a/Libraries/LibJS/Runtime/ErrorPrototype.h
+++ b/Libraries/LibJS/Runtime/ErrorPrototype.h
@@ -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&);
};
diff --git a/Libraries/LibJS/Tests/Error.prototype.name.js b/Libraries/LibJS/Tests/Error.prototype.name.js
new file mode 100644
index 0000000000..991cb92aee
--- /dev/null
+++ b/Libraries/LibJS/Tests/Error.prototype.name.js
@@ -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);
+}