Skip to content

Commit

Permalink
Add another ShadowRealm test for onerror
Browse files Browse the repository at this point in the history
This test is similar to window-onerror-runtime-error-throw.html and
window-onerror-runtime-error.html, but ensuring that the ShadowRealm
global's onerror is triggered and not the Window's onerror.

By my reading of the spec, we cannot have a test equivalent to
window-onerror-parse-error.html in ShadowRealm because
ShadowRealm.prototype.evaluate() will exit early if the given code fails
to parse.
  • Loading branch information
ptomato committed Nov 27, 2024
1 parent b855d2e commit feb313b
Showing 1 changed file with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// META: title=globalThis.onerror: runtime script errors in ShadowRealm

// https://html.spec.whatwg.org/multipage/#runtime-script-errors says what to do
// for uncaught runtime script errors, and just below describes what to do when
// onerror is a Function.

async_test(t => {
onerror = t.unreached_func("Window onerror should not be triggered");

const realm = new ShadowRealm();

realm.evaluate("var errorCount = 0;");
realm.evaluate(`(doAsserts) => {
globalThis.onerror = function(msg, url, lineno, colno, thrownValue) {
++errorCount;
doAsserts(url, lineno, colno, typeof thrownValue, String(thrownValue));
};
}`)(t.step_func((url, lineno, typeofThrownValue, stringifiedThrownValue) => {
assert_equals(url, "eval code", "correct url passed to onerror");
assert_equals(lineno, 8, "correct line number passed to onerror");
assert_equals(typeofThrownValue, "string", "thrown string passed directly to onerror");
assert_equals(stringifiedThrownValue, "bar", "correct thrown value passed to onerror");
}));

assert_throws_js(TypeError, () => realm.evaluate(`
try {
// This error is caught, so it should NOT trigger onerror.
throw "foo";
} catch (ex) {
}
// This error is NOT caught, so it should trigger onerror.
throw "bar";
`), "thrown error is wrapped in a TypeError object from the surrounding realm");

t.step_timeout(() => {
assert_equals(realm.evaluate("errorCount"), 1, "onerror should be called once");
}, 1000);
}, "onerror triggered by uncaught thrown exception in realm.evaluate");

async_test(t => {
onerror = t.unreached_func("Window onerror should not be triggered");

const realm = new ShadowRealm();

realm.evaluate("var errorCount = 0;");
realm.evaluate(`(doAsserts) => {
globalThis.onerror = function(msg, url, lineno, colno, thrownValue) {
++errorCount;
doAsserts(url, lineno, typeof thrownValue, thrownValue instanceof TypeError);
};
}`)(t.step_func((url, lineno, typeofThrownValue, isTypeError) => {
assert_equals(url, "eval code", "correct url passed to onerror");
assert_equals(lineno, 8, "correct line number passed to onerror");
assert_equals(typeofThrownValue, "object", "thrown error instance passed to onerror");
assert_true(isShadowRealmTypeError, "correct thrown value passed to onerror");
}));

assert_throws_js(TypeError, () => realm.evaluate(`
try {
// This error is caught, so it should NOT trigger onerror.
window.nonexistentproperty.oops();
} catch (ex) {
}
// This error is NOT caught, so it should trigger onerror.
window.nonexistentproperty.oops();
`), "thrown error is wrapped in a TypeError object from the surrounding realm");

t.step_timeout(() => {
assert_equals(realm.evaluate("errorCount"), 1, "onerror should be called once");
}, 1000);
}, "onerror triggered by uncaught runtime error in realm.evaluate");

0 comments on commit feb313b

Please sign in to comment.