From 63f88b1cdf6ea2bc6d570759d2751c0a4b4a721d Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Wed, 22 Jan 2025 12:08:32 +0000 Subject: [PATCH] LibWeb: Add formatters for WebIDL exception types This adds formatters for `WebIDL::Exception`, `WebIDL::SimpleException` and `WebIDL::DomException`. These are useful for displaying the content of errors when debugging --- Libraries/LibWeb/WebIDL/DOMException.h | 12 +++++++ Libraries/LibWeb/WebIDL/ExceptionOr.h | 50 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/Libraries/LibWeb/WebIDL/DOMException.h b/Libraries/LibWeb/WebIDL/DOMException.h index 2779ab783449..c463ac27ad12 100644 --- a/Libraries/LibWeb/WebIDL/DOMException.h +++ b/Libraries/LibWeb/WebIDL/DOMException.h @@ -148,3 +148,15 @@ inline JS::Completion throw_completion(GC::Ref exception) } } + +namespace AK { + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Web::WebIDL::DOMException const& exception) + { + return Formatter::format(builder, "{}: {}"sv, exception.name(), exception.message()); + } +}; + +} diff --git a/Libraries/LibWeb/WebIDL/ExceptionOr.h b/Libraries/LibWeb/WebIDL/ExceptionOr.h index 57de48ca4ee8..0cd58c1426c7 100644 --- a/Libraries/LibWeb/WebIDL/ExceptionOr.h +++ b/Libraries/LibWeb/WebIDL/ExceptionOr.h @@ -134,3 +134,53 @@ class [[nodiscard]] ExceptionOr : public ExceptionOr { }; } + +namespace AK { + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Web::WebIDL::SimpleException const& exception) + { + auto message_view = exception.message.visit( + [](String const& message) -> StringView { + return message.bytes_as_string_view(); + }, + [](StringView message) -> StringView { + return message; + }); + + return Formatter::format(builder, message_view); + } +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Web::WebIDL::Exception const& exception) + { + return exception.visit( + [&](Web::WebIDL::SimpleException const& simple_exception) -> ErrorOr { + return Formatter::format(builder, "{}"sv, simple_exception); + }, + [&](GC::Ref const& dom_exception) -> ErrorOr { + return Formatter::format(builder, "{}"sv, *dom_exception); + }, + [&](JS::Completion const& completion) -> ErrorOr { + VERIFY(completion.is_error()); + auto value = *completion.value(); + + if (value.is_object()) { + auto& object = value.as_object(); + static const JS::PropertyKey message_property_key { "message" }; + auto has_message_or_error = object.has_own_property(message_property_key); + if (!has_message_or_error.is_error() && has_message_or_error.value()) { + auto message_object = object.get_without_side_effects(message_property_key); + return Formatter::format(builder, message_object.to_string_without_side_effects()); + } + } + + return Formatter::format(builder, value.to_string_without_side_effects()); + }); + } +}; + +}