Description
This is somewhere between a feature request and a bug. My production system recently threw a StackOverflowException.
Upon further inspection I've determined that the following is happening:
- I register BrowserContext.onRequestFailed() and onRequestFinished() callbacks in order to gather page telemetry for the requests being made. In that callback, I invoke Request.response() to gather some additional details (response content length as well as some encoding-related response headers).
- I Page.navigate() to a URL.
- The page at that URL makes a considerable number of out bound requests (>100).
- I invoke Page.waitForFunction() to wait for a particular condition to be met to indicate that my process has completed.
- Playwright invokes my callback for the first request. The callback invokes Request.response(), which puts me back in the Playwright event loop (ChannelOwner.runUntil()).
- Playwright invokes my callback for the second request. The callback invokes Request.response(), which puts me back in the Playwright event loop.
- …and on and on and on.
- Execution finally reaches a stack depth that the JVM is unhappy with and a StackOverflowException is thrown.
The issue here is that the stack can't begin to unwind until the most recent Request.response() is able to return, even if every prior Request.response() is available.
It may be worth considering a more reactive model using Future/CompletableFuture and a dedicated event processing thread in Playwright to help avoid generating stacks of such depth.
For what it's worth, this would also make it much clearer to callers what data they're fetching that can be returned locally and what requires a full round trip back to the Playwright/browser process. That's often unclear, potentially leading to people making calls that are far more expensive and less reliable than they realize.