summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-04-24 18:25:05 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-24 20:11:04 +0200
commit62c7608a2575beba8427887c008d122456109a8e (patch)
treef5c5db38a9018876ff7061d0c385d56f31fa168a
parent08373090ae6914d28064eab403caf5774b4564dc (diff)
downloadserenity-62c7608a2575beba8427887c008d122456109a8e.zip
LibJS+LibWeb: Move exception logging and remove should_log_exceptions
LibWeb is now responsible for logging unhandled exceptions itself, which means set_should_log_exceptions() is no longer used and can be removed. It turned out to be not the best option for web page exception logging, as we would have no indication regarding whether the exception was later handled of not.
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.cpp25
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.h4
-rw-r--r--Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp4
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp25
4 files changed, 26 insertions, 32 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp
index c1a38a6def..84330f8e6e 100644
--- a/Userland/Libraries/LibJS/Runtime/VM.cpp
+++ b/Userland/Libraries/LibJS/Runtime/VM.cpp
@@ -272,31 +272,6 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal
void VM::throw_exception(Exception& exception)
{
- if (should_log_exceptions()) {
- auto value = exception.value();
- if (value.is_object()) {
- auto& object = value.as_object();
- auto name = object.get_without_side_effects(names.name).value_or(js_undefined());
- auto message = object.get_without_side_effects(names.message).value_or(js_undefined());
- if (name.is_accessor() || name.is_native_property() || message.is_accessor() || message.is_native_property()) {
- // The result is not going to be useful, let's just print the value. This affects DOMExceptions, for example.
- dbgln("Throwing JavaScript exception: {}", value);
- } else {
- dbgln("Throwing JavaScript exception: [{}] {}", name, message);
- }
- } else {
- dbgln("Throwing JavaScript exception: {}", value);
- }
-
- for (ssize_t i = m_call_stack.size() - 1; i >= 0; --i) {
- const auto& source_range = m_call_stack[i]->current_node->source_range();
- auto function_name = m_call_stack[i]->function_name;
- if (function_name.is_empty())
- function_name = "<anonymous>";
- dbgln(" {} at {}:{}:{}", function_name, source_range.filename, source_range.start.line, source_range.start.column);
- }
- }
-
set_exception(exception);
unwind(ScopeType::Try);
}
diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h
index e9e8c8f823..78501e0b10 100644
--- a/Userland/Libraries/LibJS/Runtime/VM.h
+++ b/Userland/Libraries/LibJS/Runtime/VM.h
@@ -54,9 +54,6 @@ public:
static NonnullRefPtr<VM> create();
~VM();
- bool should_log_exceptions() const { return m_should_log_exceptions; }
- void set_should_log_exceptions(bool b) { m_should_log_exceptions = b; }
-
Heap& heap() { return m_heap; }
const Heap& heap() const { return m_heap; }
@@ -271,7 +268,6 @@ private:
Shape* m_scope_object_shape { nullptr };
bool m_underscore_is_last_value { false };
- bool m_should_log_exceptions { false };
};
template<>
diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp
index fb01437707..44edb408d0 100644
--- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp
@@ -12,10 +12,8 @@ namespace Web::Bindings {
JS::VM& main_thread_vm()
{
static RefPtr<JS::VM> vm;
- if (!vm) {
+ if (!vm)
vm = JS::VM::create();
- vm->set_should_log_exceptions(true);
- }
return *vm;
}
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index e0cffb8965..500927fd21 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -563,6 +563,31 @@ JS::Interpreter& Document::interpreter()
vm.on_call_stack_emptied = [this] {
auto& vm = m_interpreter->vm();
vm.run_queued_promise_jobs();
+ // Note: This is not an exception check for the promise jobs, they will just leave any
+ // exception that already exists intact and never throw a new one (without cleaning it
+ // up, that is). Taking care of any previous unhandled exception just happens to be the
+ // very last thing we want to do, even after running promise jobs.
+ if (auto* exception = vm.exception()) {
+ auto value = exception->value();
+ if (value.is_object()) {
+ auto& object = value.as_object();
+ auto name = object.get_without_side_effects(vm.names.name).value_or(JS::js_undefined());
+ auto message = object.get_without_side_effects(vm.names.message).value_or(JS::js_undefined());
+ if (name.is_accessor() || name.is_native_property() || message.is_accessor() || message.is_native_property()) {
+ // The result is not going to be useful, let's just print the value. This affects DOMExceptions, for example.
+ dbgln("Unhandled JavaScript exception: {}", value);
+ } else {
+ dbgln("Unhandled JavaScript exception: [{}] {}", name, message);
+ }
+ } else {
+ dbgln("Unhandled JavaScript exception: {}", value);
+ }
+ for (auto& traceback_frame : exception->traceback()) {
+ auto& function_name = traceback_frame.function_name;
+ auto& source_range = traceback_frame.source_range;
+ dbgln(" {} at {}:{}:{}", function_name, source_range.filename, source_range.start.line, source_range.start.column);
+ }
+ }
};
m_interpreter = JS::Interpreter::create<Bindings::WindowObject>(vm, *m_window);
}