mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 05:25:32 +03:00
LibWeb: Add initial implementation of global.reportError()
This commit is contained in:
parent
34cd98a607
commit
ccb3a2f7ad
Notes:
sideshowbarker
2024-07-17 08:27:05 +09:00
Author: https://github.com/siketyan 🔰 Commit: https://github.com/LadybirdBrowser/ladybird/commit/ccb3a2f7ad Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/392 Reviewed-by: https://github.com/kennethmyhra Reviewed-by: https://github.com/mattco98 ✅ Reviewed-by: https://github.com/tcl3 ✅
@ -0,0 +1,5 @@
|
||||
message = Reporting an Error!
|
||||
filename =
|
||||
lineno = 0
|
||||
colno = 0
|
||||
error = Error: Reporting an Error!
|
@ -0,0 +1,16 @@
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
window.onerror = (message, filename, lineno, colno, error) => {
|
||||
println(`message = ${message}`);
|
||||
println(`filename = ${filename}`);
|
||||
println(`lineno = ${lineno}`);
|
||||
println(`colno = ${colno}`);
|
||||
println(`error = ${error}`);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
window.reportError(new Error('Reporting an Error!'));
|
||||
});
|
||||
</script>
|
@ -64,6 +64,7 @@ public:
|
||||
using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
|
||||
using WindowOrWorkerGlobalScopeMixin::fetch;
|
||||
using WindowOrWorkerGlobalScopeMixin::queue_microtask;
|
||||
using WindowOrWorkerGlobalScopeMixin::report_error;
|
||||
using WindowOrWorkerGlobalScopeMixin::set_interval;
|
||||
using WindowOrWorkerGlobalScopeMixin::set_timeout;
|
||||
using WindowOrWorkerGlobalScopeMixin::structured_clone;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Fetch/FetchMethod.h>
|
||||
#include <LibWeb/HTML/CanvasRenderingContext2D.h>
|
||||
#include <LibWeb/HTML/ErrorEvent.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/EventSource.h>
|
||||
#include <LibWeb/HTML/ImageBitmap.h>
|
||||
@ -742,4 +743,92 @@ JS::NonnullGCPtr<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_typ
|
||||
return *m_supported_entry_types_array;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror
|
||||
void WindowOrWorkerGlobalScopeMixin::report_error(JS::Value e)
|
||||
{
|
||||
auto& target = static_cast<DOM::EventTarget&>(this_impl());
|
||||
auto& realm = relevant_realm(target);
|
||||
auto& vm = realm.vm();
|
||||
auto script_or_module = vm.get_active_script_or_module();
|
||||
|
||||
// FIXME: Get the current position in the script.
|
||||
auto line = 0;
|
||||
auto col = 0;
|
||||
|
||||
// 1. If target is in error reporting mode, then return; the error is not handled.
|
||||
if (m_error_reporting_mode) {
|
||||
report_exception_to_console(e, realm, ErrorInPromise::No);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Let target be in error reporting mode.
|
||||
m_error_reporting_mode = true;
|
||||
|
||||
// 3. Let message be an implementation-defined string describing the error in a helpful manner.
|
||||
auto message = [&] {
|
||||
if (e.is_object()) {
|
||||
auto& object = e.as_object();
|
||||
if (MUST(object.has_own_property(vm.names.message))) {
|
||||
auto message = object.get_without_side_effects(vm.names.message);
|
||||
return message.to_string_without_side_effects();
|
||||
}
|
||||
}
|
||||
|
||||
return MUST(String::formatted("Uncaught exception: {}", e.to_string_without_side_effects()));
|
||||
}();
|
||||
|
||||
// 4. Let errorValue be the value that represents the error: in the case of an uncaught exception,
|
||||
// that would be the value that was thrown; in the case of a JavaScript error that would be an Error object
|
||||
// If there is no corresponding value, then the null value must be used instead.
|
||||
auto error_value = e;
|
||||
|
||||
// 5. Let urlString be the result of applying the URL serializer to the URL record that corresponds to the resource from which script was obtained.
|
||||
// FIXME: Use the URL of the current running script.
|
||||
auto url_string = String {};
|
||||
|
||||
// 6. If script is a classic script and script's muted errors is true, then set message to "Script error.",
|
||||
// urlString to the empty string, line and col to 0, and errorValue to null.
|
||||
script_or_module.visit(
|
||||
[&](const JS::NonnullGCPtr<JS::Script>& js_script) {
|
||||
if (verify_cast<ClassicScript>(js_script->host_defined())->muted_errors() == ClassicScript::MutedErrors::Yes) {
|
||||
message = "Script error."_string;
|
||||
url_string = String {};
|
||||
line = 0;
|
||||
col = 0;
|
||||
error_value = JS::js_null();
|
||||
}
|
||||
},
|
||||
[](auto const&) {});
|
||||
|
||||
// 7. Let notHandled be true.
|
||||
auto not_handled = true;
|
||||
|
||||
// 8. If target implements EventTarget, then set notHandled to the result of firing an event named error at target,
|
||||
// using ErrorEvent, with the cancelable attribute initialized to true, the message attribute initialized to message,
|
||||
// the filename attribute initialized to urlString, the lineno attribute initialized to line, the colno attribute initialized to col,
|
||||
// and the error attribute initialized to errorValue.
|
||||
ErrorEventInit event_init = {};
|
||||
event_init.cancelable = true;
|
||||
event_init.message = message;
|
||||
event_init.filename = url_string;
|
||||
event_init.lineno = line;
|
||||
event_init.colno = col;
|
||||
event_init.error = error_value;
|
||||
|
||||
not_handled = target.dispatch_event(ErrorEvent::create(realm, EventNames::error, event_init));
|
||||
|
||||
// 9. Let target no longer be in error reporting mode.
|
||||
m_error_reporting_mode = false;
|
||||
|
||||
// 10. If notHandled is false, then the error is handled. Otherwise, the error is not handled.
|
||||
if (not_handled) {
|
||||
// When the user agent is to report an exception E, the user agent must report the error for the relevant script,
|
||||
// with the problematic position (line number and column number) in the resource containing the script,
|
||||
// using the global object specified by the script's settings object as the target.
|
||||
// If the error is still not handled after this, then the error may be reported to a developer console.
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception
|
||||
report_exception_to_console(e, realm, ErrorInPromise::No);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
|
||||
JS::NonnullGCPtr<IndexedDB::IDBFactory> indexed_db();
|
||||
|
||||
void report_error(JS::Value e);
|
||||
|
||||
protected:
|
||||
void initialize(JS::Realm&);
|
||||
void visit_edges(JS::Cell::Visitor&);
|
||||
@ -114,6 +116,8 @@ private:
|
||||
JS::GCPtr<IndexedDB::IDBFactory> m_indexed_db;
|
||||
|
||||
mutable JS::GCPtr<JS::Object> m_supported_entry_types_array;
|
||||
|
||||
bool m_error_reporting_mode { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ interface mixin WindowOrWorkerGlobalScope {
|
||||
readonly attribute boolean isSecureContext;
|
||||
readonly attribute boolean crossOriginIsolated;
|
||||
|
||||
[FIXME] undefined reportError(any e);
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror
|
||||
undefined reportError(any e);
|
||||
|
||||
// base64 utility methods
|
||||
DOMString btoa(DOMString data);
|
||||
|
Loading…
Reference in New Issue
Block a user