CDP: Runtime.evaluate(awaitPromise) fails with ProtocolError on rejected promise
Categories
(Remote Protocol :: CDP, defect, P3)
Tracking
(firefox112 fixed)
Tracking | Status | |
---|---|---|
firefox112 | --- | fixed |
People
(Reporter: martin, Assigned: canadahonk)
References
Details
Attachments
(1 file)
User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0
Steps to reproduce:
Set up a sandbox with https://www.npmjs.com/package/chrome-remote-interface :
mkdir /tmp/test; cd /tmp/test
npm install chrome-remote-interface
node_modules/.bin/chrome-remote-interface inspect
Start firefox current nightly (both 88.0a1 from two weeks ago as well as today's 89.0a1 2021-04-02 64 bit) in a temporary home dir:
HOME=/tmp/h firefox --remote-debugging-port=9222 localhost &
Enter Chrome DevTools interactive shell:
node_modules/.bin/chrome-remote-interface inspect
Visit a page to initialize CDP, and make sure it works:
Page.navigate({url: "https://www.mozilla.org"})
{ frameId: '19', loaderId: '41044854964409' }
Runtime.evaluate({expression: "window.location.toString()"})
{ result: { type: 'string', value: 'https://www.mozilla.org/en-US/' } }
(this may take a few iterations, Firefox often fails with "can't access property "evaluate", context is null" -- but this isn't the issue here).
Do simple promise evaluation (this works fine):
Runtime.evaluate({expression: "new Promise((resolve, reject) => resolve('moo'))", awaitPromise: true})
{ result: { type: 'string', value: 'moo' } }
Runtime.evaluate({expression: "new Promise((resolve, reject) => reject(new Error('moo')))", awaitPromise: true})
{ exceptionDetails: { text: 'moo' } }
Do a slightly more complicated promise rejection evaluation where the rejection is delayed:
Runtime.evaluate({expression: "new Promise((resolve, reject) => window.setTimeout(() => reject(new Error('moo')), 500))", awaitPromise: true})
Actual results:
Uncaught:
ProtocolError: Debugger: expected Debugger.Object, got Proxy (_returnError@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:193:22
evaluate@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:173:23
setTimeout handlerSentry</an.prototype.qt/<@https://www.mozilla.org/media/js/BUNDLES/sentry.d4a49ae2b9e1.js:1:48985
@debugger eval code:1:41
@debugger eval code:1:1
evaluate@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:147:29
evaluate@chrome://remote/content/cdp/domains/content/Runtime.jsm:279:20
execute@chrome://remote/content/cdp/domains/DomainCache.jsm:101:25
receiveMessage@chrome://remote/content/cdp/sessions/ContentProcessSession.jsm:84:45
)
at /tmp/test/node_modules/chrome-remote-interface/lib/chrome.js:94:35
at Chrome._handleMessage (/tmp/test/node_modules/chrome-remote-interface/lib/chrome.js:257:17) {
request: {
method: 'Runtime.evaluate',
params: {
expression: "new Promise((resolve, reject) => window.setTimeout(() => reject(new Error('moo')), 500))",
awaitPromise: true
},
sessionId: undefined
},
response: {
message: 'Debugger: expected Debugger.Object, got Proxy',
data: '_returnError@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:193:22\n' +
'evaluate@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:173:23\n' +
'setTimeout handlerSentry</an.prototype.qt/<@https://www.mozilla.org/media/js/BUNDLES/sentry.d4a49ae2b9e1.js:1:48985\n' +
'@debugger eval code:1:41\n' +
'@debugger eval code:1:1\n' +
'evaluate@chrome://remote/content/cdp/domains/content/runtime/ExecutionContext.jsm:147:29\n' +
'evaluate@chrome://remote/content/cdp/domains/content/Runtime.jsm:279:20\n' +
'execute@chrome://remote/content/cdp/domains/DomainCache.jsm:101:25\n' +
'receiveMessage@chrome://remote/content/cdp/sessions/ContentProcessSession.jsm:84:45\n'
}
}
Expected results:
I expect the same output as with the "straight away reject", i.e. something like
{ exceptionDetails: { text: 'moo' } }
For comparison, when doing this with chromium:
rm -rf /tmp/h; HOME=/tmp/h chromium-browser --remote-debugging-port=9222 about:blank &
you get something like
{
result: {
type: 'object',
subtype: 'error',
className: 'Error',
description: 'Error: moo\n' +
' at <anonymous>:1:41\n' +
' at new Promise (<anonymous>)\n' +
' at <anonymous>:1:1',
objectId: '4319001542793249506.1.4'
},
exceptionDetails: {
exceptionId: 2,
text: 'Uncaught (in promise) Error: moo',
lineNumber: 0,
columnNumber: 0,
exception: {
type: 'object',
subtype: 'error',
className: 'Error',
description: 'Error: moo\n' +
' at <anonymous>:1:41\n' +
' at new Promise (<anonymous>)\n' +
' at <anonymous>:1:1',
objectId: '4319001542793249506.1.5'
}
}
}
Comment 1•4 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'DevTools::General' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.
Updated•4 years ago
|
Updated•4 years ago
|
Comment 2•4 years ago
|
||
Interesting. We have actually a test for a delayed resolved promise via restrict
, but there we only return a value and don't throw an error:
So something is probably wrong here with returning errors.
Updated•3 years ago
|
Reporter | ||
Comment 3•2 years ago
|
||
For the record, this is still true with Firefox 106.
Assignee | ||
Comment 4•2 years ago
|
||
Happy to work on this.
Assignee | ||
Comment 5•2 years ago
|
||
Fix an internal error causing a ProtocolError when a Promise ran using
Runtime.evaluate and rejects with an Error(), while using the
awaitPromise option. Also added test for such a case.
When a rejected Error happens, that Error (or a Proxy representing)
is thrown and caught internally instead of a Debugger.Object, unsure why.
instanceof was not working internally so requires checking if
a key exists instead. Happy to change if a better solution is found.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 7•2 years ago
|
||
bugherder |
Updated•2 years ago
|
Description
•