Skip to content
This repository has been archived by the owner on Jan 30, 2025. It is now read-only.

Request.frame is sometimes nil #90

Closed
imiric opened this issue Nov 10, 2021 · 5 comments
Closed

Request.frame is sometimes nil #90

imiric opened this issue Nov 10, 2021 · 5 comments
Assignees
Labels
bug Something isn't working next Might be eligible for the next planning (not guaranteed!)

Comments

@imiric
Copy link
Contributor

imiric commented Nov 10, 2021

Sometimes when we create a new Request here:

var frame *Frame = nil
if event.FrameID != "" {
frame = m.frameManager.getFrameByID(event.FrameID)
}
if frame == nil {
m.logger.Debugf("NetworkManager", "frame is nil")
}
req, err := NewRequest(m.ctx, event, frame, redirectChain, interceptionID, m.userReqInterceptionEnabled)

... we get a nil Frame pointer from FrameManager.getFrameByID().

The logic of how m.frames is changed is a bit convoluted, as we delete frames in a couple of places:

We added some debugging information in 0451efb so we can see when it happens, but there's likely a synchronization bug here that we need to address so that anything that needs a Frame reference (e.g. when getting the session through it for Response.fetchBody() (which we could possibly store directly on Response to avoid resolving the reference chain?)) can run before we actually delete the Frame.

@imiric imiric added bug Something isn't working next Might be eligible for the next planning (not guaranteed!) labels Nov 10, 2021
imiric referenced this issue Nov 10, 2021
This is a quick fix for #82, but the root cause is still unknown.

We added debugging information for when this happens in 0451efb, so
it's the same issue that will need a deeper lifecycle fix.
@imiric imiric self-assigned this Nov 11, 2021
@imiric
Copy link
Contributor Author

imiric commented Nov 11, 2021

Some more info about this: from testing with the script in #49, when we get a nil Frame in NetworkManager.onRequest() it's because event.FrameID == "", i.e. there's no Frame associated to the RequestWillBeSent event to lookup. In all cases these are preflight/OPTIONS requests, which typically don't have a body anyway, though this is not strictly forbidden by the spec. So if the responses have Content-Length we would emit metrics for them fine and won't rely on Response.fetchBody()/CDP.

That said, the reason fetchBody() fails so often is because calling network.GetResponseBody() shouldn't be done on the ResponseReceived event, but on the LoadingFinished one. See ChromeDevTools/devtools-protocol#44 (comment).

So the fix I'm currently working on involves emitting metrics for Response only in the LoadingFinished handler, which does produce less error fetching response body warnings, but I'm running into an issue where sometimes we don't get a ResponseReceived event before we get LoadingFinished, so the Response we set on the Request is nil. Not sure why this happens, the flow should be RequestWillBeSent -> ResponseReceived -> LoadingFinished.

An alternative to using network.GetResponseBody() and len(r.body) to emit data_received metrics could be to use EventLoadingFinished.EncodedDataLength. This seems like it would be more reliable, yet I've seen cases where this is 0.0 and len(r.body) > 0. So... 🤷‍♂️ I'll have to look deeper into this.

@inancgumus
Copy link
Member

This is in the review queue. You didn't request me to review this yet but should I add my review to this? @imiric

@imiric
Copy link
Contributor Author

imiric commented Nov 18, 2021

The PR for this is #117. It's still a draft because of the race condition it introduces, which I'm not sure how to fix yet, and well, other issues have come up in the meantime.

@imiric
Copy link
Contributor Author

imiric commented Feb 4, 2022

I think we can close this. As explained above, Frame being nil is a valid state, and we no longer panic because of it. After #117 it's being logged with more detail, and fetchBody() is more reliable, so we shouldn't see it as often.

WDYT @inancgumus?

@inancgumus
Copy link
Member

inancgumus commented Feb 4, 2022

👍

@imiric imiric closed this as completed Feb 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working next Might be eligible for the next planning (not guaranteed!)
Projects
None yet
Development

No branches or pull requests

2 participants