1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:07:36 +00:00

LibWeb: Support plain (throw) JS::Completion in WebIDL::ExceptionOr

This makes it possible to propagate exceptions from a function that
returns JS::ThrowCompletionOr via TRY() in another function that returns
WebIDL::ExceptionOr.
This commit is contained in:
Linus Groh 2022-09-25 17:52:27 +01:00
parent b9d626d6b2
commit 4461234898
2 changed files with 20 additions and 7 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021-2022, the SerenityOS developers.
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -75,6 +75,9 @@ ALWAYS_INLINE JS::Completion dom_exception_to_throw_completion(auto&& vm, auto&&
}, },
[&](JS::NonnullGCPtr<WebIDL::DOMException> const& exception) { [&](JS::NonnullGCPtr<WebIDL::DOMException> const& exception) {
return throw_completion(exception); return throw_completion(exception);
},
[&](JS::Completion const& completion) {
return completion;
}); });
} }

View file

@ -9,6 +9,7 @@
#include <AK/NonnullRefPtr.h> #include <AK/NonnullRefPtr.h>
#include <AK/Optional.h> #include <AK/Optional.h>
#include <AK/RefPtr.h> #include <AK/RefPtr.h>
#include <LibJS/Runtime/Completion.h>
#include <LibWeb/WebIDL/DOMException.h> #include <LibWeb/WebIDL/DOMException.h>
namespace Web::WebIDL { namespace Web::WebIDL {
@ -59,9 +60,18 @@ public:
{ {
} }
ExceptionOr(Variant<SimpleException, JS::NonnullGCPtr<DOMException>> exception) ExceptionOr(JS::Completion exception)
: m_exception(move(exception).template downcast<Empty, SimpleException, JS::NonnullGCPtr<DOMException>>()) : m_exception(move(exception))
{ {
auto const& completion = m_exception.get<JS::Completion>();
VERIFY(completion.is_error());
}
ExceptionOr(Variant<SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion> exception)
: m_exception(move(exception).template downcast<Empty, SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion>())
{
if (auto* completion = m_exception.template get_pointer<JS::Completion>())
VERIFY(completion->is_error());
} }
ExceptionOr(ExceptionOr&& other) = default; ExceptionOr(ExceptionOr&& other) = default;
@ -78,9 +88,9 @@ public:
return m_result.release_value(); return m_result.release_value();
} }
Variant<SimpleException, JS::NonnullGCPtr<DOMException>> exception() const Variant<SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion> exception() const
{ {
return m_exception.template downcast<SimpleException, JS::NonnullGCPtr<DOMException>>(); return m_exception.template downcast<SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion>();
} }
bool is_exception() const bool is_exception() const
@ -90,13 +100,13 @@ public:
// These are for compatibility with the TRY() macro in AK. // These are for compatibility with the TRY() macro in AK.
[[nodiscard]] bool is_error() const { return is_exception(); } [[nodiscard]] bool is_error() const { return is_exception(); }
Variant<SimpleException, JS::NonnullGCPtr<DOMException>> release_error() { return exception(); } Variant<SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion> release_error() { return exception(); }
private: private:
Optional<ValueType> m_result; Optional<ValueType> m_result;
// https://webidl.spec.whatwg.org/#idl-exceptions // https://webidl.spec.whatwg.org/#idl-exceptions
Variant<Empty, SimpleException, JS::NonnullGCPtr<DOMException>> m_exception {}; Variant<Empty, SimpleException, JS::NonnullGCPtr<DOMException>, JS::Completion> m_exception {};
}; };
template<> template<>