LibJS+LibWeb: Make DOMException hold an [[ErrorData]] slot

Split JS::ErrorData out of JS::Error so that it can be used both
by JS::Error and WebIDL::DOMException. This adds support for
Error.isError to DOMException, also letting us report DOMException
stack information to the console.
This commit is contained in:
Shannon Booth
2026-04-04 15:39:01 +02:00
committed by Shannon Booth
parent bdd9c98d44
commit 57130908b3
Notes: github-actions[bot] 2026-04-08 18:35:02 +00:00
24 changed files with 429 additions and 152 deletions

View File

@@ -35,21 +35,27 @@ void report_exception_to_console(JS::Value value, JS::Realm& realm, ErrorInPromi
} else {
dbgln("\033[31;1mUnhandled JavaScript exception{}:\033[0m [{}] {}", error_in_promise == ErrorInPromise::Yes ? " (in promise)" : "", name, message);
}
if (is<JS::Error>(object)) {
// FIXME: We should be doing this for DOMException as well
// https://webidl.spec.whatwg.org/#js-DOMException-specialness
// "Additionally, if an implementation gives native Error objects special powers or nonstandard properties (such as a stack property), it should also expose those on DOMException objects."
auto const& error_value = static_cast<JS::Error const&>(object);
dbgln("{}", error_value.stack_string(JS::CompactTraceback::Yes));
console.report_exception(error_value, error_in_promise == ErrorInPromise::Yes);
if (auto const* error_data = object.error_data()) {
String exception_name;
String exception_message;
if (auto const* exception = as_if<WebIDL::DOMException>(object)) {
exception_name = exception->name().to_string();
exception_message = MUST(exception->message().view().to_utf8());
} else {
exception_name = name.to_string_without_side_effects();
exception_message = message.to_string_without_side_effects();
}
dbgln("{}", error_data->stack_string(JS::CompactTraceback::Yes));
console.report_exception(exception_name, exception_message, *error_data, error_in_promise == ErrorInPromise::Yes);
return;
}
} else {
dbgln("\033[31;1mUnhandled JavaScript exception{}:\033[0m {}", error_in_promise == ErrorInPromise::Yes ? " (in promise)" : "", value);
}
console.report_exception(*JS::Error::create(realm, value.to_utf16_string_without_side_effects()), error_in_promise == ErrorInPromise::Yes);
auto message = value.to_string_without_side_effects();
auto error = JS::Error::create(realm, Utf16String::from_utf8(message));
console.report_exception("Error"_string, message, *error, error_in_promise == ErrorInPromise::Yes);
}
// https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception