Browse Source

LibJS: Convert install_error_cause() to ThrowCompletionOr

Linus Groh 3 years ago
parent
commit
867b19affb

+ 1 - 3
Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp

@@ -51,9 +51,7 @@ Value AggregateErrorConstructor::construct(FunctionObject& new_target)
         aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message));
         aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message));
     }
     }
 
 
-    aggregate_error->install_error_cause(vm.argument(2));
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(aggregate_error->install_error_cause(vm.argument(2)));
 
 
     auto errors_list = iterable_to_list(global_object, vm.argument(0));
     auto errors_list = iterable_to_list(global_object, vm.argument(0));
     if (vm.exception())
     if (vm.exception())

+ 20 - 9
Userland/Libraries/LibJS/Runtime/Error.cpp

@@ -5,6 +5,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
 
 
+#include <LibJS/Runtime/Completion.h>
 #include <LibJS/Runtime/Error.h>
 #include <LibJS/Runtime/Error.h>
 #include <LibJS/Runtime/GlobalObject.h>
 #include <LibJS/Runtime/GlobalObject.h>
 
 
@@ -30,18 +31,28 @@ Error::Error(Object& prototype)
 }
 }
 
 
 // 20.5.8.1 InstallErrorCause ( O, options ), https://tc39.es/proposal-error-cause/#sec-errorobjects-install-error-cause
 // 20.5.8.1 InstallErrorCause ( O, options ), https://tc39.es/proposal-error-cause/#sec-errorobjects-install-error-cause
-void Error::install_error_cause(Value options)
+ThrowCompletionOr<void> Error::install_error_cause(Value options)
 {
 {
     auto& vm = this->vm();
     auto& vm = this->vm();
+
+    // 1. If Type(options) is Object and ? HasProperty(options, "cause") is true, then
     if (!options.is_object())
     if (!options.is_object())
-        return;
-    auto& options_object = options.as_object();
-    if (!options_object.has_property(vm.names.cause))
-        return;
-    auto cause = options_object.get(vm.names.cause);
-    if (vm.exception())
-        return;
-    create_non_enumerable_data_property_or_throw(vm.names.cause, cause);
+        return {};
+    auto has_property = options.as_object().has_property(vm.names.cause);
+    if (auto* exception = vm.exception())
+        return throw_completion(exception->value());
+    if (has_property) {
+        // a. Let cause be ? Get(options, "cause").
+        auto cause = options.as_object().get(vm.names.cause);
+        if (auto* exception = vm.exception())
+            return throw_completion(exception->value());
+
+        // b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause).
+        create_non_enumerable_data_property_or_throw(vm.names.cause, cause);
+    }
+
+    // Return NormalCompletion(undefined).
+    return {};
 }
 }
 
 
 #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType)                         \
 #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType)                         \

+ 2 - 1
Userland/Libraries/LibJS/Runtime/Error.h

@@ -8,6 +8,7 @@
 #pragma once
 #pragma once
 
 
 #include <AK/FlyString.h>
 #include <AK/FlyString.h>
+#include <LibJS/Runtime/Completion.h>
 #include <LibJS/Runtime/Object.h>
 #include <LibJS/Runtime/Object.h>
 
 
 namespace JS {
 namespace JS {
@@ -22,7 +23,7 @@ public:
     explicit Error(Object& prototype);
     explicit Error(Object& prototype);
     virtual ~Error() override = default;
     virtual ~Error() override = default;
 
 
-    void install_error_cause(Value options);
+    ThrowCompletionOr<void> install_error_cause(Value options);
 };
 };
 
 
 // NOTE: Making these inherit from Error is not required by the spec but
 // NOTE: Making these inherit from Error is not required by the spec but

+ 2 - 6
Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp

@@ -48,9 +48,7 @@ Value ErrorConstructor::construct(FunctionObject& new_target)
         error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message));
         error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message));
     }
     }
 
 
-    error->install_error_cause(vm.argument(1));
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(error->install_error_cause(vm.argument(1)));
 
 
     return error;
     return error;
 }
 }
@@ -97,9 +95,7 @@ Value ErrorConstructor::construct(FunctionObject& new_target)
             error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)); \
             error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)); \
         }                                                                                                  \
         }                                                                                                  \
                                                                                                            \
                                                                                                            \
-        error->install_error_cause(vm.argument(1));                                                        \
-        if (vm.exception())                                                                                \
-            return {};                                                                                     \
+        TRY_OR_DISCARD(error->install_error_cause(vm.argument(1)));                                        \
                                                                                                            \
                                                                                                            \
         return error;                                                                                      \
         return error;                                                                                      \
     }
     }