summaryrefslogtreecommitdiff
path: root/ext/web/02_event.js
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2022-04-13 10:50:57 +0100
committerGitHub <noreply@github.com>2022-04-13 11:50:57 +0200
commit4d18f558e4cfebc5b8d9d594401e3ce74fc3226b (patch)
treead13a194d22b3318cf862d9ae5214143f891930a /ext/web/02_event.js
parentd621ce1cf01ea9bb5562ea3bbed7c2d1db799c91 (diff)
feat(ext/web): Add error events for event listener and timer errors (#14159)
- feat: Add handleable error event for even listener errors - feat: Add handleable error event for setTimeout()/setInterval() errors - feat: Add Deno.core.destructureError() - feat: Add Deno.core.terminate() - fix: Don't throw listener errors from dispatchEvent() - fix: Use biased mode when selecting between mod_evaluate() and run_event_loop() results
Diffstat (limited to 'ext/web/02_event.js')
-rw-r--r--ext/web/02_event.js52
1 files changed, 51 insertions, 1 deletions
diff --git a/ext/web/02_event.js b/ext/web/02_event.js
index 122add211..f1078b4ac 100644
--- a/ext/web/02_event.js
+++ b/ext/web/02_event.js
@@ -7,6 +7,7 @@
"use strict";
((window) => {
+ const core = window.Deno.core;
const webidl = window.__bootstrap.webidl;
const { DOMException } = window.__bootstrap.domException;
const consoleInternal = window.__bootstrap.console;
@@ -32,6 +33,7 @@
ObjectPrototypeIsPrototypeOf,
ReflectDefineProperty,
SafeArrayIterator,
+ StringPrototypeStartsWith,
Symbol,
SymbolFor,
SymbolToStringTag,
@@ -787,7 +789,11 @@
setCurrentTarget(eventImpl, tuple.item);
- innerInvokeEventListeners(eventImpl, getListeners(tuple.item));
+ try {
+ innerInvokeEventListeners(eventImpl, getListeners(tuple.item));
+ } catch (error) {
+ reportException(error);
+ }
}
function normalizeAddEventHandlerOptions(
@@ -1317,6 +1323,49 @@
});
}
+ let reportExceptionStackedCalls = 0;
+
+ // https://html.spec.whatwg.org/#report-the-exception
+ function reportException(error) {
+ reportExceptionStackedCalls++;
+ const jsError = core.destructureError(error);
+ const message = jsError.message;
+ let filename = "";
+ let lineno = 0;
+ let colno = 0;
+ if (jsError.frames.length > 0) {
+ filename = jsError.frames[0].fileName;
+ lineno = jsError.frames[0].lineNumber;
+ colno = jsError.frames[0].columnNumber;
+ } else {
+ const jsError = core.destructureError(new Error());
+ for (const frame of jsError.frames) {
+ if (
+ typeof frame.fileName == "string" &&
+ !StringPrototypeStartsWith(frame.fileName, "deno:")
+ ) {
+ filename = frame.fileName;
+ lineno = frame.lineNumber;
+ colno = frame.columnNumber;
+ break;
+ }
+ }
+ }
+ const event = new ErrorEvent("error", {
+ cancelable: true,
+ message,
+ filename,
+ lineno,
+ colno,
+ error,
+ });
+ // Avoid recursing `reportException()` via error handlers more than once.
+ if (reportExceptionStackedCalls > 1 || window.dispatchEvent(event)) {
+ core.terminate(error);
+ }
+ reportExceptionStackedCalls--;
+ }
+
window.Event = Event;
window.EventTarget = EventTarget;
window.ErrorEvent = ErrorEvent;
@@ -1333,6 +1382,7 @@
listenerCount,
};
window.__bootstrap.event = {
+ reportException,
setIsTrusted,
setTarget,
defineEventHandler,