RESOLVED FIXED 188265
Worker should support unhandled promise rejections
https://bugs.webkit.org/show_bug.cgi?id=188265
Summary Worker should support unhandled promise rejections
Yusuke Suzuki
Reported 2018-08-02 11:41:00 PDT
After microtask handling is adopted.
Attachments
Patch (6.69 KB, patch)
2018-08-07 11:24 PDT, Yusuke Suzuki
no flags
Patch (7.49 KB, patch)
2018-08-07 11:37 PDT, Yusuke Suzuki
no flags
Patch (7.51 KB, patch)
2018-08-07 11:39 PDT, Yusuke Suzuki
no flags
Patch (7.98 KB, patch)
2018-08-07 11:42 PDT, Yusuke Suzuki
no flags
Patch (11.51 KB, patch)
2018-08-11 15:55 PDT, Yusuke Suzuki
no flags
Patch (19.97 KB, patch)
2018-08-11 16:20 PDT, Yusuke Suzuki
no flags
Patch (20.84 KB, patch)
2018-08-11 16:29 PDT, Yusuke Suzuki
no flags
Patch (33.48 KB, patch)
2018-08-11 17:05 PDT, Yusuke Suzuki
no flags
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
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
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
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
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
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
Patch (57.27 KB, patch)
2018-08-12 03:49 PDT, Yusuke Suzuki
no flags
Patch (59.58 KB, patch)
2018-08-12 06:37 PDT, Yusuke Suzuki
no flags
Patch (58.98 KB, patch)
2018-08-12 17:05 PDT, Yusuke Suzuki
darin: review+
Yusuke Suzuki
Comment 1 2018-08-07 11:24:54 PDT
Yusuke Suzuki
Comment 2 2018-08-07 11:37:44 PDT
Yusuke Suzuki
Comment 3 2018-08-07 11:39:39 PDT
Yusuke Suzuki
Comment 4 2018-08-07 11:42:15 PDT
Yusuke Suzuki
Comment 5 2018-08-11 15:55:16 PDT
Yusuke Suzuki
Comment 6 2018-08-11 16:20:35 PDT
Yusuke Suzuki
Comment 7 2018-08-11 16:29:36 PDT
Yusuke Suzuki
Comment 8 2018-08-11 17:05:53 PDT
EWS Watchlist
Comment 9 2018-08-11 18:22:46 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 10 2018-08-11 18:22:48 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 11 2018-08-11 19:07:56 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 12 2018-08-11 19:07:58 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 13 2018-08-11 19:08:10 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 14 2018-08-11 19:08:12 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 15 2018-08-11 20:33:26 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 16 2018-08-11 20:33:28 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 17 2018-08-11 20:54:09 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 18 2018-08-11 20:54:11 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 19 2018-08-11 21:10:36 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 20 2018-08-11 21:10:38 PDT Comment hidden (obsolete)
Yusuke Suzuki
Comment 21 2018-08-12 03:49:48 PDT
Yusuke Suzuki
Comment 22 2018-08-12 06:37:29 PDT
Yusuke Suzuki
Comment 23 2018-08-12 17:05:44 PDT
Darin Adler
Comment 24 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.
Joseph Pecoraro
Comment 25 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.
Darin Adler
Comment 26 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.
Darin Adler
Comment 27 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"
Yusuke Suzuki
Comment 28 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.
Yusuke Suzuki
Comment 29 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.
Yusuke Suzuki
Comment 30 2018-08-14 06:04:53 PDT
Radar WebKit Bug Importer
Comment 31 2018-08-14 06:07:13 PDT
Radar WebKit Bug Importer
Comment 32 2018-08-14 06:07:19 PDT
Darin Adler
Comment 33 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.
Yusuke Suzuki
Comment 34 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.
Yusuke Suzuki
Comment 35 2018-08-14 10:45:16 PDT
Note You need to log in before you can comment on or make changes to this bug.