`Worker()` fails after `self.close()`
Categories
(Core :: DOM: Workers, defect, P3)
Tracking
()
People
(Reporter: daxpedda, Unassigned)
Details
(Whiteboard: dom-lws-bugdash-triage)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0
Steps to reproduce:
Trying to call the Worker constructor after calling DedicatedWorkerGlobalScope.close().
root:
new Worker('worker.js');
worker.js:
console.log('Hello from worker!');
self.close();
new Worker('worker.js'); // Fails here.
Actual results:
Constructing the nested worker after calling self.close() will throw an exception:
NetworkError: Worker constructor: Failed to load worker script at worker.js (nsresult = 0x80004005)
Expected results:
I'm actually not sure if this is intended or not, but other browsers, like Chrome, just do nothing instead.
I've also tried out the following:
- Used the
moduletype in the constructor. - Used a different URL in the nested constructor.
- Used Blobs in the nested constructor.
All fail with the exact same message.
Comment 2•2 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::JavaScript Engine' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 3•2 years ago
|
||
An interesting edge case, thanks for reporting this!
The reason for this error path is:
- WorkerPrivate::Constructor calls GetLoadInfo which returns NS_ERROR_FAILURE because parentStatus > Running.
- WorkerPrivate::Constructor then calls ReportLoadError which generates the NetworkError with the given string.
Note that slightly interestingly, we will have successfully acquired a StrongWorkerRef for the parent in WorkerPrivate::Constructor, but that's because the ref has the default threshold of Canceling, rather than Closing, our current status.
I think we probably should not be throwing a NetworkError here per the current spec's Worker constructor algorithm, but the spec does allow us to throw a SecurityError in step 1, and I think that's probably the right thing for us to do if we change our behavior here prior to spec changes happening relative to self.close().
There's been some discussion of making workers post self.close() behave more like detached iframes, so it may be worth considering doing the spec work to change what happens there rather than changing our behavior here to align to the current letter of the spec which is arguably not the spirit of the spec. In general, letting anything happen after self.close() introduces surface area that's primarily only of reasonable use to security researchers. (Like, one could argue that the spec allows code to do self.close() then go into an infinite loop and let a spawned worker do a bunch of things that are observable by other means like using BroadcastChannel, but it's quite reasonable in that case to say "don't call close() if you want your worker to be able to keep doing things.")
Comment 4•2 years ago
•
|
||
(This is only applicable to dedicated workers and shared workers, and not service workers, as there is no close() method on the ServiceWorkerGlobalScope.)
Updated•1 year ago
|
Updated•4 months ago
|
Description
•