Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
serializationOptions: returnByValue ? {} : { maxObjectDepth: 0, maxDomDepth: 0 },
awaitPromise: true,
userActivation: true,
});
}).catch(rewriteError);
if (response.type === 'exception')
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
if (response.type === 'success') {
Expand Down Expand Up @@ -194,6 +194,12 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
}
}

function rewriteError(error: Error): never {
if (error.message.includes('too much recursion') || error.message.includes('stack limit exceeded'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think 'InternalError: too much recursion' is a message that is thrown for any stack overflow error, not just JSON serialization. We should discriminate those from from JSON.serialize() issue. Wouldn't it be more appropriate to check for something like "TypeError: cyclic object value"
?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

'InternalError: too much recursion' is all we're getting from Firefox. Note that exceptions from the user's evaluated code won't end up here because if the evaluation throws then script.callFunction returns a response with response.type === 'exception' instead of rethrowing that exception.

throw new Error('Cannot serialize result: object reference chain is too long.');
throw error;
}

function renderPreview(remoteObject: bidi.Script.RemoteValue, nested = false): string {
switch (remoteObject.type) {
case 'undefined':
Expand Down
1 change: 0 additions & 1 deletion tests/bidi/expectations/bidi-chromium-page.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ page/page-emulate-media.spec.ts › should keep reduced motion and color emulati
page/page-emulate-media.spec.ts › should work during navigation [fail]
page/page-evaluate-no-stall.spec.ts › should throw when no main execution context [fail]
page/page-evaluate.spec.ts › should throw a nice error after a navigation [fail]
page/page-evaluate.spec.ts › should throw for too deep reference chain [fail]
page/page-evaluate.spec.ts › should throw when evaluation triggers reload [fail]
page/page-event-console.spec.ts › should not throw when there are console messages in detached iframes [fail]
page/page-event-console.spec.ts › should trigger correct Log [timeout]
Expand Down
2 changes: 2 additions & 0 deletions tests/bidi/expectations/moz-firefox-nightly-library.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
library/agent-perform.spec.ts › retrieve a secret [timeout]
library/browsercontext-add-cookies.spec.ts › should allow unnamed cookies [fail]
library/browsercontext-basic.spec.ts › fetch with keepalive should throw when offline [fail]
library/browsercontext-basic.spec.ts › should disable javascript [fail]
library/browsercontext-basic.spec.ts › should emulate media in cross-process iframe [fail]
Expand Down Expand Up @@ -134,6 +135,7 @@ library/inspector/cli-codegen-3.spec.ts › cli codegen › should generate fram
library/launcher.spec.ts › should throw a friendly error if its headed and there is no xserver on linux running [fail]
library/locator-dispatchevent-touch.spec.ts › should support touch points in touch event arguments [fail]
library/multiclient.spec.ts › last emulateMedia wins [fail]
library/multiclient.spec.ts › screencast should deliver cached last frame to a new client [fail]
library/multiclient.spec.ts › should unroute websockets [timeout]
library/page-clock.spec.ts › popup › should tick after popup [flaky]
library/page-event-crash.spec.ts › should be able to close context when page crashes [timeout]
Expand Down
4 changes: 2 additions & 2 deletions tests/page/page-evaluate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,8 @@ it('should return undefined for non-serializable objects', async ({ page }) => {

it('should throw for too deep reference chain', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/33997' }
}, async ({ page, browserName }) => {
it.fixme(browserName === 'firefox', 'Firefox Juggler -> Playwright serialiser does not throw for deep references.\nThis causes large objects to get serialised back to the Playwright client.\nThere our validators throw \'Maximum call stack size exceeded\'.');
}, async ({ page, browserName, isBidi }) => {
it.fixme(browserName === 'firefox' && !isBidi, 'Firefox Juggler -> Playwright serialiser does not throw for deep references.\nThis causes large objects to get serialised back to the Playwright client.\nThere our validators throw \'Maximum call stack size exceeded\'.');
await expect(page.evaluate(depth => {
const obj = {};
let temp = obj;
Expand Down
Loading