Common Exceptions

This guide describes the common exceptions that can be thrown when working with the DotNetBrowser library.

Initialization exceptions

License exceptions

These exceptions are thrown when the license check fails for some reason.

  • NoLicenseException is thrown when the license is missing. It usually happens when no license key is set in the EngineOptions, and DotNetBrowser cannot locate a dotnetbrowser.license file containing the license key. To troubleshoot this case, check if the license is added to the project.
  • InvalidLicenseException is thrown when the license is configured properly, but the license check fails. The exact reason of the license check failure is provided as the exception message. For instance, this exception can be thrown when the license is expired, or the product binding in the license does not match any of the namespaces.

Chromium binaries exceptions

The ChromiumBinariesMissingException is thrown when DotNetBrowser cannot launch the bound Chromium engine because the Chromium binaries are missing and cannot be restored. The actual reason of the exception is provided as the exception message. For instance, this exception can be thrown when no compatible Chromium binaries are found in the Chromium binaries directory, and DotNetBrowser cannot find an assembly containing the compatible binaries.

Other engine initialization exceptions

The EngineInitializationException is thrown when something goes wrong during initializing the IEngine instance.

User data directory is already in use

It is not allowed to create two or more IEngine instances pointing to the same user data directory, even if those IEngine instances are created in separate .NET processes. Such use case is not supported by Chromium itself and leads to unpredictable behavior and sudden crashes of the engine.

As a result, when such case is detected, the EngineInitializationException is thrown with the following message: The user data directory is already in use: <path>

Runtime exceptions

ObjectDisposedException

The ObjectDisposedException is thrown when there is an attempt to use an object which is already disposed. For example, this exception is thrown when working with:

  • some previously cached DOM element or JavaScript object after loading a different web page;
  • some frame that does not exist anymore in the browser;
  • IEngine instance, any IBrowser instances created by this engine, or any other objects related to those instances after the IEngine.Dispose() is called;
  • IEngine instance, any IBrowser instances created by this engine, or any other objects related to those instances after the Chromium crash.

ConnectionClosedException

The ConnectionClosedException is thrown when the connection to the Chromium engine appears to be closed. This exception is usually related to IEngine.Dispose() method call or a Chromium crash.

Cross-thread operation not valid

When you try to modify UI on the DotNetBrowser event, you can see System.InvalidOperationException with the following description: Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on..

DotNetBrowser fires its events through the separate threads and does not use the main UI thread for this purpose. To modify UI on the DotNetBrowser event, pass the execution to the main UI thread using Invoke and BeginInvoke in WinForms or Dispatcher.Invoke and Dispatcher.BeginInvoke in WPF. The Control.InvokeRequired property in WinForms or the Dispatcher.CheckAccess() call in WPF can be used to check if it is necessary to pass the execution.

The code samples below demonstrate how to get access to UI from another thread.

WinForms

browser.Navigation.FrameLoadFinished += (s, e) =>
{
    if (e.Frame.IsMain)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new Action(() =>
            {
                this.Title = e.Browser.Url;
            }));
        }
        else
        {
            this.Title = e.Browser.Url;
        }
    }
};
browser.Navigation.LoadUrl("https://www.teamdev.com");

WPF

browser.Navigation.FrameLoadFinished += (s, e) =>
{
    if (e.Frame.IsMain)
    {
        if (!Dispatcher.CheckAccess())
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.Title = e.Browser.Url;
            }));
        }
        else
        {
            this.Title = e.Browser.Url;
        }
    }
};
browser.Navigation.LoadUrl("https://www.teamdev.com");
Go Top