Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WPTs for parse error handling in SharedWorkers #22185

Merged

Conversation

elkurin
Copy link
Contributor

@elkurin elkurin commented Mar 11, 2020

Corresponds to #5347

This pull request adds web-platform-tests to check if parse error events invoked by shared workers are successfully caught from the constructor.

@annevk
Copy link
Member

annevk commented Mar 11, 2020

I think we should have tests for multiple SharedWorker instances as well.

@elkurin
Copy link
Contributor Author

elkurin commented Mar 12, 2020

As we discussed in #5347, the behavior of shared workers (not only about error handling) when the one shared worker is constructed several times simultaneously is not defined correctly in the spec because of the raciness you mentioned, so I'm not sure about adding the test cases with multiple SharedWorker instances.

Or did you mean differently? If so, I would appreciate if you give me a brief example.

workers/shared-worker-parse-error-failure.html Outdated Show resolved Hide resolved
const scriptURL = 'modules/resources/syntax-error.js';
const worker = new SharedWorker(scriptURL, { name: 'classic',
type: 'classic' });
return new Promise(resolve => worker.onerror = resolve);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to test that the value passed to onerror is an ErrorEvent. Also, worth testing that there are no other arguments, as window.onerror gets extra arguments but worker.onerror should not.

Maybe that is scope creep for this test... But if we don't want to test those things, then we should change the test description to say error event instead of ErrorEvent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the event we get here is not defined as ErrorEvent in the spec but Event or ErrorEvent.
https://html.spec.whatwg.org/multipage/indices.html#event-error
I seems better to modify the description as you said.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: FireFox returns Event here.
https://bugzilla.mozilla.org/show_bug.cgi?id=1610438

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event is correct. The spec says "fire an event" with no constructor arg, and step 1 of https://dom.spec.whatwg.org/#concept-event-fire says to use Event.

The index is a non-normative summary of every event named error in the entire HTML spec. You have to look at individual "fire an event" sites to see which constructor they use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon reviewing the spec PR I think it's actually important that we test the type (and arguments) here. This is test of new functionality and it's easy to get it wrong. We should be sure that it gets test coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the test to check if the event's type is 'error'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, by "type" I actually meant "constructor". Please test its .constructor property, and also check the number of arguments sent to onerror.

Copy link
Contributor Author

@elkurin elkurin Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for taking it in the wrong way. I modified as you suggested.
I found the test to check onerror for dedicated workers:
https://github.com/web-platform-tests/wpt/blob/master/workers/constructors/Worker/AbstractWorker.onerror.html
and it seems that this test should be also merged into wpt/workers/modules/dedicated-worker-parse-error-failure.html so that we can test parse error occurred in statically imported scripts (but not in this PR).

@annevk
Copy link
Member

annevk commented Mar 13, 2020

I guess I'm okay splitting things up.

worker.onerror = reject;
});
assert_array_equals(msg.data, ['export-on-load-script.js']);
if (msg.data.length == 1 && msg.data[0] === 'export-on-load-script.js') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the assert fails then this line will not be reached, so this if condition is redundant.

I think the best way to do this is to convert this all into a promise_setup().

promise_setup(async () => {
  const worker = new SharedWorker('resources/static-import-worker.js',
                                  { type: 'module' });

  const supportsModuleWorkers = await new Promise((resolve, reject) => {
    worker.port.onmessage = e => resolve(e.data.length === 1 && e.data[0] == 'export-on-load-script.js');
    worker.onerror = () => resolve(false);
  });

  assert_precondition(supportsModuleWorkers, "Static import must be supported on module shared worker to run this test.");
});

Then you can remove the assert_precondition from each individual test. Also it makes it so that there are only 2 tests, both with precondition failures, instead of 1 test with a failure and 2 tests with precondition failures.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I modified in this way.

@wpt-pr-bot
Copy link
Collaborator

There are no reviewers for this pull request. Please reach out on W3C's irc server (irc.w3.org, port 6665) on channel #testing (web client) to get help with this. Thank you!

@elkurin
Copy link
Contributor Author

elkurin commented Mar 19, 2020

@domenic Sorry, I did something wrong with with GIt commits, and got many non-related labels. Could remove those?

assert_equals(typeof args.a.message, 'string', 'Event.message');
assert_equals(args.a.filename, location.href + '/resources/syntax-error.js'),
'Event.filename');
assert_equals(args.a.lineno, 1, 'Event.lineno');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right. Event does not have messsage, filename, or lineno properties. Does this test somehow pass in Chrome?

I'd expectt the test to check that these properties do not exist...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't understand the difference between Event and ErrorEvent.
Chromium doesn't have this message, filename or lineno value for shared workers but has on dedicated workers.
I removed it.

const scriptURL = 'resources/syntax-error.js';
const worker = new SharedWorker(scriptURL, { type: 'module' });
const args = await new Promise(resolve =>
worker.onerror = (a, b, c) => resolve({a, b, c}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a little simpler as

  const args = await new Promise(resolve => worker.onerror = (...args) => resolve(args));

and then args will be an array, which avoids the awkward a/b/c properties and lets the checkArguments function do something like assert_equals(args.length, 1).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Modified.

);
});

const checkArguments = (args) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To deduplicate this you may want to move it to a file in workers/resources, change it to window.checkErrorArguments = ..., and then use e.g. <script src="resources/check-error-arguments.js"></script> to get the function in both files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created workers/support/check-error-arguments.js.

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits. Thank you for your patience!

worker.port.onmessage = e => {
resolve(e.data.length == 1 && e.data[0] == 'export-on-load-script.js');
};
worker.onerror = () => reject(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
worker.onerror = () => reject(false);
worker.onerror = () => resolve(false);

window.checkErrorArguments = args => {
assert_equals(args.length, 1);
assert_equals(args[0].constructor, Event);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
};

@elkurin
Copy link
Contributor Author

elkurin commented Mar 23, 2020

Thanks so much @domenic for a lot of comments!

@dbaron dbaron removed their request for review March 23, 2020 17:22
@domenic domenic merged commit bd6c94e into web-platform-tests:master Mar 23, 2020
blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this pull request Mar 25, 2020
This CL handles parse error events in modules shared workers.
By this change, parse error events invoked by top-level scripts and
statically imported scripts can be handled by AbstractWorker.onerror.

The HTML spec defines script parsing should occur during the fetch step
and invoke a parse error event at that point if needed. This CL obeys
this behavior for module script workers, but not for classic script
workers because of an implementation reason that classic script workers
are supposed to parse the script during the evaluation step. Therefore,
the timing to catch parse error events differs.
In this CL, parse error handling is only implemented for module shared
workers, not for classic.

This is discussed in the html spec issue:
whatwg/html#5323

The wpt to check this feature will be added from external github:
web-platform-tests/wpt#22185


Bug: 1058259
Change-Id: I2397a7de8e2ae732fb0b29aea8d8703dd2a79a05
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2100058
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Eriko Kurimoto <elkurin@google.com>
Cr-Commit-Position: refs/heads/master@{#753185}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants