Windows WebView2 Error when calling goToURL while another is loading

I’m using Webview2 for a WebBrowserComponent and am finding that if goToURL is called while a page is loading it can sometimes lead to garbled rendering in the component and text that says “Error 9” instead of having the page load correctly. This can easily happen if there’s a button to navigate to a page in the UI and the user clicks it multiple times, or initiates another navigation while one is in progress. I’ve done some web searches and found this GitHub issue on another (non-JUCE) project that seems similar: StageWebView2: Loading URLs sometimes causes Error "3228" (Load error: 9.) · Issue #1641 · airsdk/Adobe-Runtime-Support · GitHub

Does anyone know of some workarounds for this in JUCE?

With the help of a few people on Discord I tracked the issue down to this code.

Based on reading the docs for add_NavigationCompleted it seems that no specific handling is required for the error case because the WebView will display an error page automatically if necessary.

So in my own copy of JUCE I removed this error handling case. I left the if (success) case so owner.pageFinishedLoading is only called if the page actually finishes loading. With this change, I’m able to trigger new page loads as many times and as rapidly as I want and I don’t get any corrupted renders or error messages in the web view. I think the JUCE team should consider making this change. If anything, the failure case should call a user-defined callback instead of redirecting to a URL that just shows a cryptic error.

Thoughts?

@reuk

Thanks for reporting this, this appears to be a bug indeed.

Calling goToURL() before the current page finished loading generates a COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED error, but after that the new page load operation could still complete successfully if it wasn’t hijacked by the code you pointed out.

I’ll have to think about the wording of the docs for WebBrowserComponent::pageLoadHadNetworkError(), to see if this requires a fix on our part.

As it stands I think you could also achieve the required behaviour by overriding the function and returning false, to prevent proceeding to the error page.

Thanks for the suggestion, I’ve implemented this as a workaround for now:

bool WebBrowserComponent::pageLoadHadNetworkError (const juce::String& errorString)
{
#if JUCE_WINDOWS
    if (errorString.startsWith("Error code: 9")) return false;
#endif
    return juce::WebBrowserComponent::pageLoadHadNetworkError (errorString);
}