diff --git a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp index eb25aa711a..5fdfbdbb34 100644 --- a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp @@ -48,7 +48,7 @@ Value AggregateErrorConstructor::construct(FunctionObject& new_target) auto message = vm.argument(1).to_string(global_object); if (vm.exception()) return {}; - aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)); + MUST(aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); } TRY_OR_DISCARD(aggregate_error->install_error_cause(vm.argument(2))); diff --git a/Userland/Libraries/LibJS/Runtime/Error.cpp b/Userland/Libraries/LibJS/Runtime/Error.cpp index 2555868641..51f0195b30 100644 --- a/Userland/Libraries/LibJS/Runtime/Error.cpp +++ b/Userland/Libraries/LibJS/Runtime/Error.cpp @@ -46,7 +46,7 @@ ThrowCompletionOr Error::install_error_cause(Value options) auto cause = TRY(options.as_object().get(vm.names.cause)); // b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause). - create_non_enumerable_data_property_or_throw(vm.names.cause, cause); + MUST(create_non_enumerable_data_property_or_throw(vm.names.cause, cause)); } // Return NormalCompletion(undefined). diff --git a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp index 243cf3279e..c108374734 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp @@ -45,7 +45,7 @@ Value ErrorConstructor::construct(FunctionObject& new_target) auto message = vm.argument(0).to_string(global_object); if (vm.exception()) return {}; - error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)); + MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); } TRY_OR_DISCARD(error->install_error_cause(vm.argument(1))); @@ -53,51 +53,51 @@ Value ErrorConstructor::construct(FunctionObject& new_target) return error; } -#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ - ConstructorName::ConstructorName(GlobalObject& global_object) \ - : NativeFunction(*static_cast(global_object.error_constructor())) \ - { \ - } \ - \ - void ConstructorName::initialize(GlobalObject& global_object) \ - { \ - auto& vm = this->vm(); \ - NativeFunction::initialize(global_object); \ - \ - /* 20.5.6.2.1 NativeError.prototype, \ - https://tc39.es/ecma262/#sec-nativeerror.prototype */ \ - define_direct_property(vm.names.prototype, global_object.snake_name##_prototype(), 0); \ - \ - define_direct_property(vm.names.length, Value(1), Attribute::Configurable); \ - } \ - \ - ConstructorName::~ConstructorName() { } \ - \ - /* 20.5.6.1.1 NativeError ( message ), https://tc39.es/ecma262/#sec-nativeerror */ \ - Value ConstructorName::call() \ - { \ - return construct(*this); \ - } \ - \ - /* 20.5.6.1.1 NativeError ( message ), https://tc39.es/ecma262/#sec-nativeerror */ \ - Value ConstructorName::construct(FunctionObject& new_target) \ - { \ - auto& vm = this->vm(); \ - auto& global_object = this->global_object(); \ - \ - auto* error = TRY_OR_DISCARD(ordinary_create_from_constructor( \ - global_object, new_target, &GlobalObject::snake_name##_prototype)); \ - \ - if (!vm.argument(0).is_undefined()) { \ - auto message = vm.argument(0).to_string(global_object); \ - if (vm.exception()) \ - return {}; \ - error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)); \ - } \ - \ - TRY_OR_DISCARD(error->install_error_cause(vm.argument(1))); \ - \ - return error; \ +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ + ConstructorName::ConstructorName(GlobalObject& global_object) \ + : NativeFunction(*static_cast(global_object.error_constructor())) \ + { \ + } \ + \ + void ConstructorName::initialize(GlobalObject& global_object) \ + { \ + auto& vm = this->vm(); \ + NativeFunction::initialize(global_object); \ + \ + /* 20.5.6.2.1 NativeError.prototype, \ + https://tc39.es/ecma262/#sec-nativeerror.prototype */ \ + define_direct_property(vm.names.prototype, global_object.snake_name##_prototype(), 0); \ + \ + define_direct_property(vm.names.length, Value(1), Attribute::Configurable); \ + } \ + \ + ConstructorName::~ConstructorName() { } \ + \ + /* 20.5.6.1.1 NativeError ( message ), https://tc39.es/ecma262/#sec-nativeerror */ \ + Value ConstructorName::call() \ + { \ + return construct(*this); \ + } \ + \ + /* 20.5.6.1.1 NativeError ( message ), https://tc39.es/ecma262/#sec-nativeerror */ \ + Value ConstructorName::construct(FunctionObject& new_target) \ + { \ + auto& vm = this->vm(); \ + auto& global_object = this->global_object(); \ + \ + auto* error = TRY_OR_DISCARD(ordinary_create_from_constructor( \ + global_object, new_target, &GlobalObject::snake_name##_prototype)); \ + \ + if (!vm.argument(0).is_undefined()) { \ + auto message = vm.argument(0).to_string(global_object); \ + if (vm.exception()) \ + return {}; \ + MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); \ + } \ + \ + TRY_OR_DISCARD(error->install_error_cause(vm.argument(1))); \ + \ + return error; \ } JS_ENUMERATE_NATIVE_ERRORS diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index acfe9e0716..92b4ef57d4 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -183,16 +183,20 @@ ThrowCompletionOr Object::create_data_property_or_throw(PropertyName const } // 7.3.6 CreateNonEnumerableDataPropertyOrThrow ( O, P, V ), https://tc39.es/proposal-error-cause/#sec-createnonenumerabledatapropertyorthrow -bool Object::create_non_enumerable_data_property_or_throw(PropertyName const& property_name, Value value) +ThrowCompletionOr Object::create_non_enumerable_data_property_or_throw(PropertyName const& property_name, Value value) { VERIFY(!value.is_empty()); VERIFY(property_name.is_valid()); + auto& vm = this->vm(); // 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }. auto new_description = PropertyDescriptor { .value = value, .writable = true, .enumerable = false, .configurable = true }; // 2. Return ? DefinePropertyOrThrow(O, P, newDesc). - return define_property_or_throw(property_name, new_description); + auto result = define_property_or_throw(property_name, new_description); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); + return result; } // 7.3.8 DefinePropertyOrThrow ( O, P, desc ), https://tc39.es/ecma262/#sec-definepropertyorthrow diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index bd50043884..8e49134e8b 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -80,7 +80,7 @@ public: ThrowCompletionOr create_data_property(PropertyName const&, Value); ThrowCompletionOr create_method_property(PropertyName const&, Value); ThrowCompletionOr create_data_property_or_throw(PropertyName const&, Value); - bool create_non_enumerable_data_property_or_throw(PropertyName const&, Value); + ThrowCompletionOr create_non_enumerable_data_property_or_throw(PropertyName const&, Value); bool define_property_or_throw(PropertyName const&, PropertyDescriptor const&); bool delete_property_or_throw(PropertyName const&); bool has_property(PropertyName const&) const;