Bug 188265 - Worker should support unhandled promise rejections
Summary: Worker should support unhandled promise rejections
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on: 188246
Blocks: 188551
  Show dependency treegraph
 
Reported: 2018-08-02 11:41 PDT by Yusuke Suzuki
Modified: 2018-08-14 10:45 PDT (History)
12 users (show)

See Also:


Attachments
Patch (6.69 KB, patch)
2018-08-07 11:24 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (7.49 KB, patch)
2018-08-07 11:37 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (7.51 KB, patch)
2018-08-07 11:39 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (7.98 KB, patch)
2018-08-07 11:42 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (11.51 KB, patch)
2018-08-11 15:55 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (19.97 KB, patch)
2018-08-11 16:20 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (20.84 KB, patch)
2018-08-11 16:29 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (33.48 KB, patch)
2018-08-11 17:05 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews101 for mac-sierra (2.30 MB, application/zip)
2018-08-11 18:22 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews121 for ios-simulator-wk2 (9.70 MB, application/zip)
2018-08-11 19:07 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews115 for mac-sierra (3.04 MB, application/zip)
2018-08-11 19:08 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews104 for mac-sierra-wk2 (2.81 MB, application/zip)
2018-08-11 20:33 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews117 for mac-sierra (3.03 MB, application/zip)
2018-08-11 20:54 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews126 for ios-simulator-wk2 (9.96 MB, application/zip)
2018-08-11 21:10 PDT, EWS Watchlist
no flags Details
Patch (57.27 KB, patch)
2018-08-12 03:49 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (59.58 KB, patch)
2018-08-12 06:37 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (58.98 KB, patch)
2018-08-12 17:05 PDT, Yusuke Suzuki
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2018-08-02 11:41:00 PDT
After microtask handling is adopted.
Comment 1 Yusuke Suzuki 2018-08-07 11:24:54 PDT
Created attachment 346718 [details]
Patch
Comment 2 Yusuke Suzuki 2018-08-07 11:37:44 PDT
Created attachment 346719 [details]
Patch
Comment 3 Yusuke Suzuki 2018-08-07 11:39:39 PDT
Created attachment 346720 [details]
Patch
Comment 4 Yusuke Suzuki 2018-08-07 11:42:15 PDT
Created attachment 346721 [details]
Patch
Comment 5 Yusuke Suzuki 2018-08-11 15:55:16 PDT
Created attachment 346970 [details]
Patch
Comment 6 Yusuke Suzuki 2018-08-11 16:20:35 PDT
Created attachment 346971 [details]
Patch
Comment 7 Yusuke Suzuki 2018-08-11 16:29:36 PDT
Created attachment 346972 [details]
Patch
Comment 8 Yusuke Suzuki 2018-08-11 17:05:53 PDT
Created attachment 346973 [details]
Patch
Comment 9 EWS Watchlist 2018-08-11 18:22:46 PDT Comment hidden (obsolete)
Comment 10 EWS Watchlist 2018-08-11 18:22:48 PDT Comment hidden (obsolete)
Comment 11 EWS Watchlist 2018-08-11 19:07:56 PDT Comment hidden (obsolete)
Comment 12 EWS Watchlist 2018-08-11 19:07:58 PDT Comment hidden (obsolete)
Comment 13 EWS Watchlist 2018-08-11 19:08:10 PDT Comment hidden (obsolete)
Comment 14 EWS Watchlist 2018-08-11 19:08:12 PDT Comment hidden (obsolete)
Comment 15 EWS Watchlist 2018-08-11 20:33:26 PDT Comment hidden (obsolete)
Comment 16 EWS Watchlist 2018-08-11 20:33:28 PDT Comment hidden (obsolete)
Comment 17 EWS Watchlist 2018-08-11 20:54:09 PDT Comment hidden (obsolete)
Comment 18 EWS Watchlist 2018-08-11 20:54:11 PDT Comment hidden (obsolete)
Comment 19 EWS Watchlist 2018-08-11 21:10:36 PDT Comment hidden (obsolete)
Comment 20 EWS Watchlist 2018-08-11 21:10:38 PDT Comment hidden (obsolete)
Comment 21 Yusuke Suzuki 2018-08-12 03:49:48 PDT
Created attachment 346985 [details]
Patch
Comment 22 Yusuke Suzuki 2018-08-12 06:37:29 PDT
Created attachment 346986 [details]
Patch
Comment 23 Yusuke Suzuki 2018-08-12 17:05:44 PDT
Created attachment 346992 [details]
Patch
Comment 24 Darin Adler 2018-08-13 10:44:21 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

> Source/WebCore/dom/Microtasks.h:73
> +    WEBCORE_EXPORT static MicrotaskQueue& queueForScriptExecutionContext(ScriptExecutionContext*);

This should take a reference, not a pointer. I believe it does not allow passing a nullptr.

I’m not a huge fan of writing out the entire class name of an argument as part of a function name: it’s common in Objective-C but doesn’t seem right in C++ where we have much stronger type checking. I could imagine just naming this function "queue" or "contextQueue" or maybe "queueForContext" or "queueForExecutionContext".

> Source/WebCore/workers/WorkerThread.cpp:304
> +            workerGlobalScope.removeRejectedPromiseTracker();

I’m starting to think that this long list of things to stop in WorkerGlobalScope might belong inside that class, not in this WorkerThread function.
Comment 25 Joseph Pecoraro 2018-08-13 11:59:30 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

Awesome! r=me as well.

> Source/WebCore/ChangeLog:51
> +        * dom/ScriptExecutionContext.cpp:
> +        (WebCore::ScriptExecutionContext::removeRejectedPromiseTracker):
> +        * dom/ScriptExecutionContext.h:

This one could use an explanation. We don't do this teardown in documents but you are doing it in workers. Was there a particular cycle this prevents?

> Source/WebCore/html/HTMLAttributeNames.in:273
> +onrejectionhandled

I thought this file was specific to element attribute names. Meaning cases like `<element attrname="...">`.

Is it the case that onrejectionhandled/onunhandledrejection can be attribute names on a particular element? Or am I mis-understanding this file's purpose?

> LayoutTests/http/wpt/workers/promise-unhandled-rejection.any.worker-expected.txt:1
> +CONSOLE MESSAGE: line 1774: TypeError: null is not an object (evaluating 'this.message_target.removeEventListener')

Interesting, do you know what this message_target is and why we are failing these tests? Can always be done in a follow-up for sure, but its just weird.
Comment 26 Darin Adler 2018-08-13 17:06:38 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

>> Source/WebCore/html/HTMLAttributeNames.in:273
>> +onrejectionhandled
> 
> I thought this file was specific to element attribute names. Meaning cases like `<element attrname="...">`.
> 
> Is it the case that onrejectionhandled/onunhandledrejection can be attribute names on a particular element? Or am I mis-understanding this file's purpose?

Oh, good point. I am not sure I understand why these needed to be added.
Comment 27 Darin Adler 2018-08-13 17:09:23 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

> LayoutTests/http/wpt/workers/promise-unhandled-rejection.any.js:14
> +}, "UnhaneldRejection event occurs if a rejected promise is not handled.");

Just spotted a typo here: "Unhaneld"
Comment 28 Yusuke Suzuki 2018-08-14 05:40:24 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

>> Source/WebCore/ChangeLog:51
>> +        * dom/ScriptExecutionContext.h:
> 
> This one could use an explanation. We don't do this teardown in documents but you are doing it in workers. Was there a particular cycle this prevents?

In Workers, VM bound to the worker will be destroyed when the worker finishes. So before destroying the VM, we need to destroy RejectedPromiseTracker.
Otherwise, RejectedPromiseTracker requires VM in its destruction. This is why we have the teardown procedure for workers.

>> Source/WebCore/dom/Microtasks.h:73
>> +    WEBCORE_EXPORT static MicrotaskQueue& queueForScriptExecutionContext(ScriptExecutionContext*);
> 
> This should take a reference, not a pointer. I believe it does not allow passing a nullptr.
> 
> I’m not a huge fan of writing out the entire class name of an argument as part of a function name: it’s common in Objective-C but doesn’t seem right in C++ where we have much stronger type checking. I could imagine just naming this function "queue" or "contextQueue" or maybe "queueForContext" or "queueForExecutionContext".

Make sense! I like contextQueue :) Renamed.
And passing reference here :)

>>> Source/WebCore/html/HTMLAttributeNames.in:273
>>> +onrejectionhandled
>> 
>> I thought this file was specific to element attribute names. Meaning cases like `<element attrname="...">`.
>> 
>> Is it the case that onrejectionhandled/onunhandledrejection can be attribute names on a particular element? Or am I mis-understanding this file's purpose?
> 
> Oh, good point. I am not sure I understand why these needed to be added.

Ah, right. It is unnecessary since they are only in Window/Worker. Removed.

>> Source/WebCore/workers/WorkerThread.cpp:304
>> +            workerGlobalScope.removeRejectedPromiseTracker();
> 
> I’m starting to think that this long list of things to stop in WorkerGlobalScope might belong inside that class, not in this WorkerThread function.

Sounds super nice! I've added `WorkerGlobalScope::prepareForTermination` and move these things to that function.

>> LayoutTests/http/wpt/workers/promise-unhandled-rejection.any.worker-expected.txt:1
>> +CONSOLE MESSAGE: line 1774: TypeError: null is not an object (evaluating 'this.message_target.removeEventListener')
> 
> Interesting, do you know what this message_target is and why we are failing these tests? Can always be done in a follow-up for sure, but its just weird.

This "message_target" is in WPT test harness. I guess this is a bug in WPT test harness, which shows this failure if worker reports unhandledrejection.
Comment 29 Yusuke Suzuki 2018-08-14 05:58:48 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

>>> LayoutTests/http/wpt/workers/promise-unhandled-rejection.any.worker-expected.txt:1
>>> +CONSOLE MESSAGE: line 1774: TypeError: null is not an object (evaluating 'this.message_target.removeEventListener')
>> 
>> Interesting, do you know what this message_target is and why we are failing these tests? Can always be done in a follow-up for sure, but its just weird.
> 
> This "message_target" is in WPT test harness. I guess this is a bug in WPT test harness, which shows this failure if worker reports unhandledrejection.

Ah, I've found the bug. Our worker has a bug in reporting error messages to console.
WorkerGlobalScope::logExceptionToConsole emits error event to the host Worker object by using WorkerMessagingProxy::postExceptionToWorkerObject.
This code would be good for usual JS exception. But it is not correct for reporting "Unhandled Promise Rejection" to the host console.
Since this is existing bug, I'll fix this in a subsequent patch.
Comment 30 Yusuke Suzuki 2018-08-14 06:04:53 PDT
Committed r234846: <https://trac.webkit.org/changeset/234846>
Comment 31 Radar WebKit Bug Importer 2018-08-14 06:07:13 PDT
<rdar://problem/43282647>
Comment 32 Radar WebKit Bug Importer 2018-08-14 06:07:19 PDT
<rdar://problem/43282650>
Comment 33 Darin Adler 2018-08-14 09:04:52 PDT
Comment on attachment 346992 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=346992&action=review

A couple very small things I noticed after this was landed.

> Source/WebCore/bindings/js/JSExecState.cpp:39
>      ScriptExecutionContext* context = scriptExecutionContextFromExecState(exec);

Tiny picky point: If this result is guaranteed to be non-null, it would be great to put it in a reference rather than a pointer. All the other call sites for scriptExecutionContextFromExecState check for null, so this one is unusual in that it knows it’s not going to be null. Almost worth a comment explaining why we know. Or could consider changing this to silently do nothing in that case. Or possibly do all three: write comment about why it’s not null, assert that it’s not null, and silently do nothing in the release build.

> Source/WebCore/dom/Microtasks.cpp:59
> +    ASSERT(context->isWorkerGlobalScope());
> +    return downcast<WorkerGlobalScope>(*context).microtaskQueue();

This assertion is the same check that downcast does. There’s no need to assert just before calling downcast since that’s the entire purpose of downcast, to build the assertion into the cast.
Comment 34 Yusuke Suzuki 2018-08-14 10:41:08 PDT
(In reply to Darin Adler from comment #33)
> Comment on attachment 346992 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=346992&action=review
> 
> A couple very small things I noticed after this was landed.

Thank you, I'll land a follow-up patch to fix these points.

> 
> > Source/WebCore/bindings/js/JSExecState.cpp:39
> >      ScriptExecutionContext* context = scriptExecutionContextFromExecState(exec);
> 
> Tiny picky point: If this result is guaranteed to be non-null, it would be
> great to put it in a reference rather than a pointer. All the other call
> sites for scriptExecutionContextFromExecState check for null, so this one is
> unusual in that it knows it’s not going to be null. Almost worth a comment
> explaining why we know. Or could consider changing this to silently do
> nothing in that case. Or possibly do all three: write comment about why it’s
> not null, assert that it’s not null, and silently do nothing in the release
> build.

I think silently doing nothing is OK. When ScriptExecutionContext is gone, we do not need to drain microtasks.
Fixed.

> 
> > Source/WebCore/dom/Microtasks.cpp:59
> > +    ASSERT(context->isWorkerGlobalScope());
> > +    return downcast<WorkerGlobalScope>(*context).microtaskQueue();
> 
> This assertion is the same check that downcast does. There’s no need to
> assert just before calling downcast since that’s the entire purpose of
> downcast, to build the assertion into the cast.

Nice catch. Removed.
Comment 35 Yusuke Suzuki 2018-08-14 10:45:16 PDT
Committed r234854: <https://trac.webkit.org/changeset/234854>