@@ -35,6 +35,7 @@ public BrowserForm()
3535 browser . StatusMessage += OnBrowserStatusMessage ;
3636 browser . TitleChanged += OnBrowserTitleChanged ;
3737 browser . AddressChanged += OnBrowserAddressChanged ;
38+ browser . LoadError += OnBrowserLoadError ;
3839
3940 var version = string . Format ( "Chromium: {0}, CEF: {1}, CefSharp: {2}" ,
4041 Cef . ChromiumVersion , Cef . CefVersion , Cef . CefSharpVersion ) ;
@@ -53,6 +54,34 @@ public BrowserForm()
5354 DisplayOutput ( string . Format ( "{0}, {1}" , version , environment ) ) ;
5455 }
5556
57+ private async void OnBrowserLoadError ( object sender , LoadErrorEventArgs e )
58+ {
59+ //Actions that trigger a download will raise an aborted error.
60+ //Aborted is generally safe to ignore
61+ if ( e . ErrorCode == CefErrorCode . Aborted )
62+ {
63+ return ;
64+ }
65+
66+ //using LoadHtml/LoadUrl creates an additional history entry that
67+ //prevents the back button from working correctly.
68+ //Use Devools Page.SetDocumentContent to change the content
69+ using ( var client = browser . GetDevToolsClient ( ) )
70+ {
71+ var response = await client . Page . GetFrameTreeAsync ( ) ;
72+ var frames = response . FrameTree ;
73+ var mainFrame = frames . Frame ;
74+
75+ var errorHtml = string . Format ( "<html><body><h2>Failed to load URL {0} with error {1} ({2}).</h2></body></html>" ,
76+ e . FailedUrl , e . ErrorText , e . ErrorCode ) ;
77+
78+ _ = client . Page . SetDocumentContentAsync ( mainFrame . Id , errorHtml ) ;
79+
80+ //AddressChanged isn't called for failed Urls so we need to manually update the Url TextBox
81+ this . InvokeOnUiThreadIfRequired ( ( ) => urlTextBox . Text = e . FailedUrl ) ;
82+ }
83+ }
84+
5685 private void OnIsBrowserInitializedChanged ( object sender , EventArgs e )
5786 {
5887 var b = ( ( ChromiumWebBrowser ) sender ) ;
0 commit comments