diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 0b4c3eaf969..c53cfa63a5a 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -1992,6 +1992,14 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@@overload_suffi [[maybe_unused]] auto& realm = *vm.current_realm(); )~~~"); + // NOTE: Create a wrapper lambda so that if the function steps return an exception, we can return that in a rejected promise. + if (function.return_type->name() == "Promise"sv) { + function_generator.append(R"~~~( + auto steps = [&realm, &vm]() -> JS::ThrowCompletionOr> { + (void)realm; +)~~~"); + } + if (is_static_function == StaticFunction::No) { function_generator.append(R"~~~( auto* impl = TRY(impl_from(vm)); @@ -2053,6 +2061,26 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@@overload_suffi )~~~"); } + if (function.return_type->name() == "Promise"sv) { + // https://webidl.spec.whatwg.org/#dfn-create-operation-function + // If we had an exception running the steps and are meant to return a Promise, wrap that exception in a rejected promise. + function_generator.append(R"~~~( + return retval; + }; + + auto maybe_retval = steps(); + + // And then, if an exception E was thrown: + // 1. If op has a return type that is a promise type, then return ! Call(%Promise.reject%, %Promise%, «E»). + // 2. Otherwise, end these steps and allow the exception to propagate. + // NOTE: We know that this is a Promise return type statically by the IDL. + if (maybe_retval.is_throw_completion()) + return WebIDL::create_rejected_promise(realm, maybe_retval.error_value())->promise(); + + auto retval = maybe_retval.release_value(); +)~~~"); + } + generate_return_statement(generator, *function.return_type, interface); function_generator.append(R"~~~( diff --git a/Tests/LibWeb/Text/expected/wpt-import/streams/readable-byte-streams/read-min.any.txt b/Tests/LibWeb/Text/expected/wpt-import/streams/readable-byte-streams/read-min.any.txt index 3425da19bb8..15d8b121814 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/streams/readable-byte-streams/read-min.any.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/streams/readable-byte-streams/read-min.any.txt @@ -6,11 +6,10 @@ Rerun Found 24 tests -23 Pass -1 Fail +24 Pass Details Result Test Name MessagePass ReadableStream with byte source: read({ min }) rejects if min is 0 -Fail ReadableStream with byte source: read({ min }) rejects if min is negative +Pass ReadableStream with byte source: read({ min }) rejects if min is negative Pass ReadableStream with byte source: read({ min }) rejects if min is larger than view's length (Uint8Array) Pass ReadableStream with byte source: read({ min }) rejects if min is larger than view's length (Uint16Array) Pass ReadableStream with byte source: read({ min }) rejects if min is larger than view's length (DataView)