diff --git a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp index e0b8cab60c..eb25aa711a 100644 --- a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp +++ b/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->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)); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/Error.cpp b/Userland/Libraries/LibJS/Runtime/Error.cpp index 838cdcec1c..3124ef88d2 100644 --- a/Userland/Libraries/LibJS/Runtime/Error.cpp +++ b/Userland/Libraries/LibJS/Runtime/Error.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include @@ -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 -void Error::install_error_cause(Value options) +ThrowCompletionOr Error::install_error_cause(Value options) { auto& vm = this->vm(); + + // 1. If Type(options) is Object and ? HasProperty(options, "cause") is true, then 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) \ diff --git a/Userland/Libraries/LibJS/Runtime/Error.h b/Userland/Libraries/LibJS/Runtime/Error.h index 765ff8d27b..c2f47c86c3 100644 --- a/Userland/Libraries/LibJS/Runtime/Error.h +++ b/Userland/Libraries/LibJS/Runtime/Error.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include namespace JS { @@ -22,7 +23,7 @@ public: explicit Error(Object& prototype); virtual ~Error() override = default; - void install_error_cause(Value options); + ThrowCompletionOr install_error_cause(Value options); }; // NOTE: Making these inherit from Error is not required by the spec but diff --git a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp index b31c328786..243cf3279e 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/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->install_error_cause(vm.argument(1)); - if (vm.exception()) - return {}; + TRY_OR_DISCARD(error->install_error_cause(vm.argument(1))); 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->install_error_cause(vm.argument(1)); \ - if (vm.exception()) \ - return {}; \ + TRY_OR_DISCARD(error->install_error_cause(vm.argument(1))); \ \ return error; \ }