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

Edge: Strange error when disposing a new Browser instance immediately after creating it #1664

Open
merks opened this issue Dec 14, 2024 · 12 comments
Labels
edge Edge Browser

Comments

@merks
Copy link
Contributor

merks commented Dec 14, 2024

When using the latest target platform, starting the installer logs exceptions like this:

!MESSAGE No more handles [0x8007139f]
!STACK 0
org.eclipse.swt.SWTError: No more handles [0x8007139f]
	at org.eclipse.swt.SWT.error(SWT.java:4962)
	at org.eclipse.swt.browser.Edge.error(Edge.java:225)
	at org.eclipse.swt.browser.Edge.setupBrowser(Edge.java:600)
	at org.eclipse.swt.browser.Edge.lambda$10(Edge.java:580)
	at org.eclipse.swt.browser.Edge.lambda$5(Edge.java:232)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3693)
	at org.eclipse.oomph.setup.internal.installer.Installer.runEventLoop(Installer.java:382)
	at org.eclipse.oomph.setup.internal.installer.SimpleInstallerDialog.runEventLoop(SimpleInstallerDialog.java:1001)
	at org.eclipse.oomph.setup.internal.installer.AbstractSimpleDialog.show(AbstractSimpleDialog.java:195)
	at org.eclipse.oomph.setup.internal.installer.InstallerApplication.run(InstallerApplication.java:295)
	at org.eclipse.oomph.setup.internal.installer.InstallerApplication.start(InstallerApplication.java:401)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1454)

I was messing around with the code that tests whether a browser can be created:

  public static synchronized boolean isBrowserAvailable()
  {
    if (browserAvailable == null)
    {
      syncExec(new Runnable()
      {
        @Override
        public void run()
        {
          Shell shell = null;

          try
          {
            shell = new Shell();
            new Browser(shell, SWT.NONE);
            while (shell.getDisplay().readAndDispatch())
            {
            }
            browserAvailable = true;
          }
          catch (SWTError ex)
          {
            browserAvailable = false;
          }
          finally
          {
            try
            {
              shell.dispose();
            }
            catch (Exception ex)
            {
              // Ignore.
            }
          }
        }
      });
    }

    return browserAvailable;
  }

Adding the while (shell.getDisplay().readAndDispatch()) makes the problem go away, so I think if one creates a browser and disposes it, there are maybe still events processed later for that browser that fail in this strange way. Does anything guard that you aren't trying to process something for a disposed Edge instance?

@merks
Copy link
Contributor Author

merks commented Dec 16, 2024

I'm also seeing this in my console with the installer and when launching an IDE upon termination.

[1216/090005.320:ERROR:window_impl.cc(121)] Failed to unregister class Chrome_WidgetWin_0. Error = 1411

@Phillipus
Copy link
Contributor

Phillipus commented Dec 16, 2024

[1216/090005.320:ERROR:window_impl.cc(121)] Failed to unregister class Chrome_WidgetWin_0. Error = 1411

I've seen that for a long time using Edge in our RCP app. If you do a web search on that message you'll find that it's been around for a long time.

And see #1498

@sratz
Copy link
Member

sratz commented Dec 16, 2024

The error handling in

void setupBrowser(int hr, long pv) {
if(browser.isDisposed()) {
browserDispose(new Event());
return;
}
switch (hr) {
case COM.S_OK:
break;
case COM.E_WRONG_THREAD:
containingEnvironment.instances().remove(this);
error(SWT.ERROR_THREAD_INVALID_ACCESS, hr);
break;
default:
containingEnvironment.instances().remove(this);
error(SWT.ERROR_NO_HANDLES, hr);
}
might not be sufficient.

In this case I think we are seeing 'The creation will fail with E_ABORT if parentWindow is destroyed before the creation is finished.' according to https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment#createcorewebview2controller.

Defaulting to NO_MORE_HANDLES as error code does not seem ideal to me in general.

@sratz sratz added the edge Edge Browser label Dec 16, 2024
@sratz sratz changed the title Strange error when disposing a new Browser instance immediately after creating it Edge: Strange error when disposing a new Browser instance immediately after creating it Dec 16, 2024
@fedejeanne
Copy link
Contributor

cc @amartya4256 , @akoch-yatta

@merks
Copy link
Contributor Author

merks commented Dec 16, 2024

FYI, this workaround works okay:

  public static synchronized boolean isBrowserAvailable()
  {
    if (browserAvailable == null)
    {
      syncExec(new Runnable()
      {
        @Override
        public void run()
        {
          try
          {
            Shell shell = new Shell();
            shell.getDisplay().asyncExec(() -> {
              try
              {
                shell.dispose();
              }
              catch (Exception ex)
              {
                // Ignore.
              }
            });

            new Browser(shell, SWT.NONE);
            browserAvailable = true;
          }
          catch (SWTError ex)
          {
            browserAvailable = false;
          }
        }
      });
    }

    return browserAvailable;
  }

The workaround above broke other logic that relied on posting events for delays processing...

@fedejeanne
Copy link
Contributor

This error shows up also in the builds in master (GH Actions) e.g. right after merging #1673

image

I added it to our board: vi-eclipse/Eclipse-Platform#163

@HeikoKlare
Copy link
Contributor

In this case I think we are seeing 'The creation will fail with E_ABORT if parentWindow is destroyed before the creation is finished.' according to https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment#createcorewebview2controller.

I agree that we need to implement that case. I actually have a branch lying around to implement this but forgot to propose a PR from it so far. I will do that today.

Still, that does not seem to be the issue that we face here. The error code for an aborted operation is 0x80004004.
The error code we have here is 0x8007139f, which means: The group or resource is not in the correct state to perform the requested operation.
According to a quick web search, this may arise when there is still a WebView process running for the same data folder for which you try to create a new WebView environment.

HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue Jan 2, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to eclipse-platform#1664
HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue Jan 2, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to
eclipse-platform#1664
HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue Jan 2, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to
eclipse-platform#1664
@HeikoKlare
Copy link
Contributor

I just found that I actually already created an according PR:

That one also adds specific handling for the error that we see reported here (error code 139f). I've updated the PR, so that we can further process it.
But note that the PR will only result in a "proper" error message for the case we see in this issue and not a fix for the root cause. The root cause might be related to multiple WebView2 processes running on the same data folder (with potentially different configurations), but the workaround of Ed rather indicates that it seems to be an issue of initialization order / timing.

@amartya4256
Copy link
Contributor

Found this related to the error code 139f here: MicrosoftEdge/WebView2Feedback#2495

@amartya4256
Copy link
Contributor

@merks Is there anyway I can reproduce it locally? I can't manage to reproduce the exception using the SDK product.

HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue Jan 3, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to
eclipse-platform#1664
HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue Jan 3, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to
eclipse-platform#1664
@merks
Copy link
Contributor Author

merks commented Jan 3, 2025

If you provision an IDE with both Oomph and SWT:

image

then you should be able to reproduce it there. If the targlet task fails, just perform the setup tasks again.

You can go back to before this commit:

image

But when I tried that, I can't reproduce the problem anymore now either. So I'm not sure what commits all changed the behavior or what else might have changed...

In any case, the changes I made to avoid the problem are just fine, so I'm okay if this problem is simply closed because surely this must be come strange corner case.

@HeikoKlare
Copy link
Contributor

Thank you, Ed! I cannot reproduce the issue with just starting the installer from the workspace either. I am only able to produce the issue when I start the installer with an explicitly changed Edge browser configuration while having an installer with the original Edge browser configuration running:

!ENTRY org.eclipse.oomph.setup.installer 4 0 2025-01-04 09:34:47.379
!MESSAGE No more handles [0x8007139f]
!STACK 0
org.eclipse.swt.SWTError: No more handles [0x8007139f]
	at org.eclipse.swt.SWT.error(SWT.java:4962)
	at org.eclipse.swt.browser.Edge.error(Edge.java:225)
	at org.eclipse.swt.browser.Edge.setupBrowser(Edge.java:601)
	at org.eclipse.swt.browser.Edge.lambda$10(Edge.java:581)
	at org.eclipse.swt.browser.Edge.lambda$5(Edge.java:232)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3693)
	at org.eclipse.oomph.setup.internal.installer.Installer.runEventLoop(Installer.java:382)

That is somehow "expected" as that's exactly the case where this error should be thrown. The data folder is, by default, placed in a subfolder of your AppData folder, named according to the Eclipse application. So for the installer, it is: "C:\Users\YOUR_NAME\AppData\Local\Eclipse Installer"

So assuming that there was actually another Eclipse application named "Eclipse Installer" running at the same time when you faced the issue, the question remains why that one had a different configuration of the Edge browser. I could imagine that it may be because the other application was running with a different localization. Or maybe you had some other installer based on a different build (using some other configuration) running at the same time.

No matter which configuration was different, starting another Edge instance with a different configuration on the same data folder should actually be the one reason specified by Microsoft causing that error. So for me the question is whether this was really a corner case or whether it is something that may happen more often and requires some improvement. In "usual" Eclipse applications (with a workspace) this will not happen because the data directory is placed within the workspace metadata folder instead of the AppData folder. On solution to avoid that multiple applications having the same name use the same Edge data folder might be to of a different identifier used to create that folder withint the AppData folder, such as encoding the file system path to the application or the like.

HeikoKlare added a commit that referenced this issue Jan 7, 2025
There is currently only few handling for failures during initialization
of an Edge browser / WebView instance. The Microsoft documentation
provides further information on this, in particular:
- ERROR_INVALID_STATE indicates that multiple Edge instances with the
same data folder but different environment options exist
- E_ABORT indicates an active abortion of the initialization process
- On any other non-OK return value than the above ones, the app should
retry initialization of the instance; to avoid endless waiting, the
number of retries is currently limited to 5

This change adds appropriate handling for these scenarios, consisting of
uniform rollback logic when the initialization fails or is aborted and
retry logic to make repeated creation attempts.

Contributes to
#1664
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
edge Edge Browser
Projects
None yet
Development

No branches or pull requests

6 participants