New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature(Page): evaluate should return a special message in case of non serialisable returned value #2425
Conversation
…n serializable returned value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think returning a predefined string is a good way to do this - puppeteer should probably reject
on that.
@benjamingr - yes, we already had this discussion here. I also agree an error is better here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think returning a predefined string is a good way to do this - puppeteer should probably reject on that.
@benjamingr We were trying to reject before and got a pushback from our clients. Users shouldn't be afraid to evaluate any expression, regardless of its return value.
What would be the usecase to justify this change?
- There's always a
page.evaluateHandle
that returns a handle for the object, if needed. - The "serializability" of the object could be checked easily, trying to
JSON.stringify
it manually.
cc @Janpot who had thoughts on this topic as well.
@@ -209,6 +209,10 @@ class Helper { | |||
apiCoverage = new Map(); | |||
} | |||
|
|||
static getNonSerializableMessage() { | |||
return 'Non serializable object returned from evaluate'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of returning a string, this should be a Symbol exposed on the puppeteer
namespace. This way you'll be able to do the following:
const result = await page.evaluate(() => window);
if (result === puppeteer.NON_SERIALIZABLE_OBJECT) {
// ...
}
w.r.t. API design, I have to agree with @benjamingr. But @aslushnikov explained to me that the current approach was a pragmatic choice as many users seem to want to do things like: await page.evaluate(() => window.foo = window); Personally, I have no idea what's the use-case behind that code, but I think we could educate people to instead do: await page.evaluate(() => {
window.foo = window;
}); Maybe the error message can include a link to a documentation page on github that explains this pattern? |
@Janpot can you please give a few examples? |
That's an interesting point. In general I think seralization could use some love. |
We were running an external library in await page.evaluate(() => {
const obj = {};
obj.a = obj;
return obj;
});
// undefined I think it's very reasonable to assume And then there was also this issue #2021. I think APIs should be intuitive and having magical third states is not intuitive I think. |
@Janpot just so we're clear - there is no hard limitation meaning puppeteer can't deal with returning recursive references, object methods, complex values (like buffers) or other things - only the fact the code for it hasn't been written in I suggest we fix that instead of the error messages |
I am familiar with the limitations 🙂. I only proposed the error message as a compromise since there seems to be concern users won't understand why their code is broken. |
This ambiguity in evaluation results is indeed uncomfortable; throwing an error would be more logical here. Postponing this until 2.0 since this will be a breaking change for our clients. |
This PR is a followup for the following discussion: #2418 (comment)
I wasn't sure which message do we want for each scenario, and how exactly do we want to implement the entire feature (if we want it at all...). So it is a start - we can discuss it from here.
it will fix #2420