2022-02-07 15:12:41 +01:00
/*
* Copyright ( c ) 2022 , David Tuin < davidot @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <AK/TypeCasts.h>
2022-10-08 19:38:32 +04:00
# include <LibJS/Console.h>
# include <LibJS/Runtime/ConsoleObject.h>
2022-02-07 15:12:41 +01:00
# include <LibJS/Runtime/VM.h>
# include <LibJS/Runtime/Value.h>
2022-10-08 19:38:32 +04:00
# include <LibWeb/Bindings/MainThreadVM.h>
2022-02-07 15:12:41 +01:00
# include <LibWeb/HTML/Scripting/ExceptionReporter.h>
2024-03-20 06:43:17 -06:00
# include <LibWeb/WebIDL/DOMException.h>
2022-02-07 15:12:41 +01:00
namespace Web : : HTML {
2022-10-08 19:38:32 +04:00
void report_exception_to_console ( JS : : Value value , JS : : Realm & realm , ErrorInPromise error_in_promise )
2022-02-07 15:12:41 +01:00
{
2022-10-08 19:38:32 +04:00
auto & console = realm . intrinsics ( ) . console_object ( ) - > console ( ) ;
2022-06-27 19:53:22 +01:00
if ( value . is_object ( ) ) {
auto & object = value . as_object ( ) ;
2022-02-07 15:12:41 +01:00
auto & vm = object . vm ( ) ;
2025-04-04 23:16:34 +02:00
auto name = object . get_without_side_effects ( vm . names . name ) ;
auto message = object . get_without_side_effects ( vm . names . message ) ;
2022-02-07 15:12:41 +01:00
if ( name . is_accessor ( ) | | message . is_accessor ( ) ) {
// The result is not going to be useful, let's just print the value. This affects DOMExceptions, for example.
2024-03-20 06:43:17 -06:00
if ( is < WebIDL : : DOMException > ( object ) ) {
auto const & exception = static_cast < WebIDL : : DOMException const & > ( object ) ;
dbgln ( " \033 [31;1mUnhandled JavaScript exception{}: \033 [0m {}: {} " , error_in_promise = = ErrorInPromise : : Yes ? " (in promise) " : " " , exception . name ( ) , exception . message ( ) ) ;
} else {
dbgln ( " \033 [31;1mUnhandled JavaScript exception{}: \033 [0m {} " , error_in_promise = = ErrorInPromise : : Yes ? " (in promise) " : " " , JS : : Value ( & object ) ) ;
}
2022-02-07 15:12:41 +01:00
} else {
2022-06-27 19:53:22 +01:00
dbgln ( " \033 [31;1mUnhandled JavaScript exception{}: \033 [0m [{}] {} " , error_in_promise = = ErrorInPromise : : Yes ? " (in promise) " : " " , name , message ) ;
2022-02-07 15:12:41 +01:00
}
if ( is < JS : : Error > ( object ) ) {
2024-03-20 06:43:17 -06:00
// 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."
2022-02-07 15:12:41 +01:00
auto const & error_value = static_cast < JS : : Error const & > ( object ) ;
2023-10-31 21:55:17 +01:00
dbgln ( " {} " , error_value . stack_string ( JS : : CompactTraceback : : Yes ) ) ;
2022-10-08 19:38:32 +04:00
console . report_exception ( error_value , error_in_promise = = ErrorInPromise : : Yes ) ;
return ;
2022-02-07 15:12:41 +01:00
}
} else {
2022-10-08 19:38:32 +04:00
dbgln ( " \033 [31;1mUnhandled JavaScript exception{}: \033 [0m {} " , error_in_promise = = ErrorInPromise : : Yes ? " (in promise) " : " " , value ) ;
2022-02-07 15:12:41 +01:00
}
2022-10-08 19:38:32 +04:00
2025-08-07 19:31:52 -04:00
console . report_exception ( * JS : : Error : : create ( realm , value . to_utf16_string_without_side_effects ( ) ) , error_in_promise = = ErrorInPromise : : Yes ) ;
2022-02-07 15:12:41 +01:00
}
2025-02-04 13:01:46 +01:00
// https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception
2022-10-08 19:38:32 +04:00
void report_exception ( JS : : Completion const & throw_completion , JS : : Realm & realm )
2022-06-27 19:53:22 +01:00
{
VERIFY ( throw_completion . type ( ) = = JS : : Completion : : Type : : Throw ) ;
2025-04-04 18:11:45 +02:00
report_exception_to_console ( throw_completion . value ( ) , realm , ErrorInPromise : : No ) ;
2022-06-27 19:53:22 +01:00
}
2022-02-07 15:12:41 +01:00
}