Skip to content
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

fix: don't reject loadURL() promise from did-fail-load - use did-finish-load instead #40661

Merged
merged 4 commits into from Dec 12, 2023

Conversation

tzahola
Copy link
Contributor

@tzahola tzahola commented Nov 30, 2023

Description of Change

Fixes this issue: #40640

The promise from WebContents.loadURL() rejects as soon as it receives did-fail-load. However, did-fail-load will be followed by a did-finish-load, which means that if the client code immediately issues another loadURL() when the promise rejects, this loadURL() will be resolved by the previous call's did-finish-load.

This PR changes the did-fail-load handler to only note the failure, and leave it to did-finish-load to actually resolve/reject the promise.

Checklist

Release Notes

Notes: Fixed WebContents.loadURL() incorrectly failing if called immediately after a previous call to loadURL() failed.

Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

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

This seems broadly reasonable, but the WebContentsObserver docs make it seem like did-finish-load won't always be called:

  // This method is invoked when the load is done, i.e. the spinner of the tab
  // will stop spinning, and the onload event was dispatched.
  //
  // If the WebContents is displaying replacement content, e.g. network error
  // pages, DidFinishLoad is invoked for frames that were not sending
  // navigational events before. It is safe to ignore these events.
  virtual void DidFinishLoad(RenderFrameHost* render_frame_host,
                             const GURL& validated_url) {}

  // This method is like DidFinishLoad, but when the load failed or was
  // cancelled, e.g. window.stop() is invoked.
  virtual void DidFailLoad(RenderFrameHost* render_frame_host,
                           const GURL& validated_url,
                           int error_code) {}

How sure are we that did-finish-load is always called after did-fail-load is dispatched?

Also, a relevant test is failing :)

@tzahola
Copy link
Contributor Author

tzahola commented Nov 30, 2023

How sure are we that did-finish-load is always called after did-fail-load is dispatched?

As far as I can tell, the call hierarchy is linear (i.e. no other path leads to WebContentsObserver::DidFailLoad), and looks like this:

  1. DocumentLoader::LoadFailed
  2. LocalFrameClientImpl::DispatchDidFailLoad
  3. WebLocalFrameImpl::DidFailLoad
  4. RenderFrameHostImpl::DidFailLoadWithError
  5. WebContentsImpl::DidFailLoadWithError
  6. WebContentsObserver::DidFailLoad

And DocumentLoader::LoadFailed issues the "failed" and "finished" calls right after another:

void DocumentLoader::LoadFailed(const ResourceError& error) {
...
  state_ = kSentDidFinishLoad;
  GetLocalFrameClient().DispatchDidFailLoad(error, history_commit_type);
  GetFrameLoader().DidFinishNavigation(
      FrameLoader::NavigationFinishState::kFailure);
  DCHECK_EQ(kSentDidFinishLoad, state_);
  params_ = nullptr;
}

@tzahola
Copy link
Contributor Author

tzahola commented Nov 30, 2023

Also, a relevant test is failing 🙂

Yes, it seems that the Electron WebContents is in certain cases dispatching did-fail-load multiple times within a single load sequence, and my implementation returns the last of these.

Actually, it was did-stop-loading emitted after did-fail-load. But now it's fixed. Also added a test (verified that it fails on the current main).

@tzahola tzahola requested a review from nornagon December 1, 2023 14:57
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened in the last 24 hours label Dec 7, 2023
@nornagon nornagon added semver/patch backwards-compatible bug fixes no-backport labels Dec 12, 2023
@nornagon nornagon merged commit a94fb2c into electron:main Dec 12, 2023
21 of 22 checks passed
Copy link

release-clerk bot commented Dec 12, 2023

Release Notes Persisted

Fixed WebContents.loadURL() incorrectly failing if called immediately after a previous call to loadURL() failed.

@tzahola
Copy link
Contributor Author

tzahola commented Dec 13, 2023

Can we backport this to 27?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-backport semver/patch backwards-compatible bug fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants