Commit a815b5a7 authored by Hiroshige Hayashizaki's avatar Hiroshige Hayashizaki Committed by Commit Bot

[WPT] Check worker.onerror message

This CL checks that worker.onerror event's `message` field
contains the original exception's message, "TypeError", etc.

This is a regression test for crbug/590219, where Chromium
set the message to just "Uncaught ".

This CL also refactors `exception-in-onerror.js` and renames it
to `throw.js`, to share it from multiple test files.

Bug: 590219
Change-Id: I7184eba7a9a6a7f08b1ef6eed95bc49adb91fcdd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368621
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarDominic Farolino <dom@chromium.org>
Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804142}
parent ab4c6d0b
...@@ -59,28 +59,28 @@ for (const type of ['classic', 'module']) { ...@@ -59,28 +59,28 @@ for (const type of ['classic', 'module']) {
const workerOptions = type === 'module' ? {type: 'module'}: {}; const workerOptions = type === 'module' ? {type: 'module'}: {};
const worker1 = new Worker( const worker1 = new Worker(
'exception-in-onerror.js?throw-in-worker-initialization', 'throw.js?throw-in-toplevel&throw-in-onerror',
workerOptions); workerOptions);
expectErrors( expectErrors(
worker1, worker1,
'Throw in worker initialization: ' + type, 'Throw in worker initialization: ' + type,
['Throw in worker initialization', 'Throw in error handler']); ['Throw in toplevel', 'Throw in error handler']);
const worker2 = new Worker( const worker2 = new Worker(
'exception-in-onerror.js?throw-in-setTimeout-function', workerOptions); 'throw.js?throw-in-setTimeout-function&throw-in-onerror', workerOptions);
expectErrors( expectErrors(
worker2, worker2,
'Throw in setTimeout(function): ' + type, 'Throw in setTimeout(function): ' + type,
['Throw in setTimeout function', 'Throw in error handler']); ['Throw in setTimeout function', 'Throw in error handler']);
const worker3 = new Worker( const worker3 = new Worker(
'exception-in-onerror.js?throw-in-setTimeout-string', workerOptions); 'throw.js?throw-in-setTimeout-string&throw-in-onerror', workerOptions);
expectErrors( expectErrors(
worker3, worker3,
'Throw in setTimeout(string): ' + type, 'Throw in setTimeout(string): ' + type,
['Throw in setTimeout string', 'Throw in error handler']); ['Throw in setTimeout string', 'Throw in error handler']);
const worker4 = new Worker('exception-in-onerror.js', workerOptions); const worker4 = new Worker('throw.js?throw-in-onerror', workerOptions);
worker4.postMessage('foo'); worker4.postMessage('foo');
expectErrors( expectErrors(
worker4, worker4,
......
onerror = function() {
throw new Error('Throw in error handler');
return false;
};
onmessage = function() {
throw new Error('Throw in message handler');
return false;
};
if (self.location.href.indexOf(
'throw-in-worker-initialization') >= 0) {
throw new Error('Throw in worker initialization');
}
if (self.location.href.indexOf(
'throw-in-setTimeout-function') >= 0) {
// To test the behavior of setTimeout(), raw setTimeout() is used.
setTimeout(() => { throw new Error('Throw in setTimeout function') }, 0);
}
if (self.location.href.indexOf(
'throw-in-setTimeout-string') >= 0) {
// To test the behavior of setTimeout(), raw setTimeout() is used.
setTimeout("throw new Error('Throw in setTimeout string')", 0);
}
This is a testharness.js-based test.
PASS Throw Error in toplevel: classic: listener
PASS Throw Error in toplevel: classic: handler
PASS Throw Error in toplevel: module: listener
PASS Throw Error in toplevel: module: handler
FAIL Throw DOMException-TypeError in toplevel: classic: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in toplevel: classic: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in toplevel: module: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in toplevel: module: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
PASS Throw Error in setTimeout-function: classic: listener
PASS Throw Error in setTimeout-function: classic: handler
PASS Throw Error in setTimeout-function: module: listener
PASS Throw Error in setTimeout-function: module: handler
PASS Throw DOMException-TypeError in setTimeout-function: classic: listener
PASS Throw DOMException-TypeError in setTimeout-function: classic: handler
PASS Throw DOMException-TypeError in setTimeout-function: module: listener
PASS Throw DOMException-TypeError in setTimeout-function: module: handler
PASS Throw Error in setTimeout-string: classic: listener
PASS Throw Error in setTimeout-string: classic: handler
PASS Throw Error in setTimeout-string: module: listener
PASS Throw Error in setTimeout-string: module: handler
FAIL Throw DOMException-TypeError in setTimeout-string: classic: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in setTimeout-string: classic: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in setTimeout-string: module: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
FAIL Throw DOMException-TypeError in setTimeout-string: module: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
PASS Throw Error in onmessage: classic: listener
PASS Throw Error in onmessage: classic: handler
PASS Throw Error in onmessage: module: listener
PASS Throw Error in onmessage: module: handler
PASS Throw DOMException-TypeError in onmessage: classic: listener
PASS Throw DOMException-TypeError in onmessage: classic: handler
PASS Throw DOMException-TypeError in onmessage: module: listener
PASS Throw DOMException-TypeError in onmessage: module: handler
PASS Throw Error in onerror: classic: listener
PASS Throw Error in onerror: classic: handler
PASS Throw Error in onerror: module: listener
PASS Throw Error in onerror: module: handler
PASS Throw DOMException-TypeError in onerror: classic: listener
PASS Throw DOMException-TypeError in onerror: classic: handler
PASS Throw DOMException-TypeError in onerror: module: listener
PASS Throw DOMException-TypeError in onerror: module: handler
Harness: the test ran to completion.
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// The error's `message` values in Worker error event handlers are tested.
// While not explicitly specified in the HTML spec, we expect some information
// about thrown errors (e.g. original message, the string "TypeError", etc.)
// to appear in the `message`.
function prepareHandler(t, error, expectedCount) {
t.step_timeout(() => assert_unreached('timeout'), 2000);
let count = 0;
return t.step_func(e => {
e.preventDefault();
assert_regexp_match(
e.message,
/Throw in/,
'e.message should contain the message of the thrown error');
if (error === 'DOMException-TypeError') {
assert_regexp_match(e.message, /TypeError/);
}
++count;
if (count >= expectedCount) {
t.done();
}
});
}
function expectErrors(worker, error, expectedCount, title) {
async_test(t => {
worker.addEventListener('error',
prepareHandler(t, error, expectedCount));
}, title+ ': listener');
async_test(t => {
worker.onerror = prepareHandler(t, error, expectedCount);
}, title + ': handler');
}
for (const location of ['toplevel',
'setTimeout-function',
'setTimeout-string',
'onmessage',
'onerror']) {
for (const error of ['Error', 'DOMException-TypeError']) {
for (const type of ['classic', 'module']) {
const worker = new Worker(
'throw.js?throw-in-' + location + '&error=' + error,
{type});
let expectedCount = 1;
if (location === 'onmessage') {
// This makes the worker's message handler to throw an error.
worker.postMessage('foo');
}
if (location === 'onerror') {
// This makes the worker's message handler to throw an error,
// AND worker's error handler to throw another error.
// Therefore we expect two errors here.
worker.postMessage('foo');
expectedCount = 2;
}
expectErrors(worker, error, expectedCount,
'Throw ' + error + ' in ' + location + ': ' + type);
}
}
}
</script>
const params = new URL(self.location.href).searchParams;
self.createError = (message) => {
if (params.get('error') === 'DOMException-TypeError') {
return new DOMException(message, 'TypeError');
} else {
return new Error(message);
}
};
onerror = function() {
if (params.has('throw-in-onerror')) {
throw createError('Throw in error handler');
}
return false;
};
onmessage = function() {
throw createError('Throw in message handler');
return false;
};
if (params.has('throw-in-toplevel')) {
throw createError('Throw in toplevel');
}
// We don't use step_timeout() here, because we have to test the behavior of
// setTimeout() without wrappers.
if (params.has('throw-in-setTimeout-function')) {
setTimeout(() => { throw createError('Throw in setTimeout function') }, 0);
}
if (params.has('throw-in-setTimeout-string')) {
setTimeout("throw createError('Throw in setTimeout string')", 0);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment