@@ -298,8 +298,8 @@ class WebViewWrapper {
298298
299299class WebViewProvider {
300300
301- private CompletableFuture <WebViewWrapper > webViewWrapperFuture = new CompletableFuture <> ();
302- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
301+ private CompletableFuture <WebViewWrapper > webViewWrapperFuture = initializeWebViewFutureWithTimeOut ();
302+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
303303
304304 ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
305305 long [] ppv = new long [1 ];
@@ -316,10 +316,23 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
316316 return webView ;
317317 }
318318
319+ private CompletableFuture <WebViewWrapper > initializeWebViewFutureWithTimeOut () {
320+ CompletableFuture <WebViewWrapper > webViewWrapperFuture = new CompletableFuture <>();
321+ webViewWrapperFuture .orTimeout (3 , TimeUnit .SECONDS ).exceptionally (exception -> {
322+ releaseEnvironment ();
323+ // Needs to be executed on the display thread since the exceptionally spawns a different thread
324+ browser .getDisplay ().execute (() -> replaceWithErrorLabel ());
325+ // Throw exception on the Display thread directly to prevent CompletableFuture
326+ // to wrap the exception and throw it silently
327+ browser .getDisplay ().execute (() -> SWT .error (SWT .ERROR_UNSPECIFIED , exception , "Edge Browser initialization timed out" ));
328+ return null ;
329+ });
330+ return webViewWrapperFuture ;
331+ }
332+
319333 private void abortInitialization () {
320334 webViewWrapperFuture .cancel (true );
321335 }
322-
323336 private ICoreWebView2_2 initializeWebView_2 (ICoreWebView2 webView ) {
324337 long [] ppv = new long [1 ];
325338 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_2 , ppv );
@@ -571,6 +584,15 @@ private String getDataDir(Display display) {
571584 return dataDir ;
572585}
573586
587+ private void replaceWithErrorLabel () {
588+ Label errorLabel = new Label (browser .getParent (), SWT .WRAP );
589+ errorLabel .setForeground (browser .getDisplay ().getSystemColor (SWT .COLOR_RED ));
590+ errorLabel .setText ("Edge browser initialization failed" );
591+ errorLabel .setLocation (0 , 0 );
592+ errorLabel .setSize (browser .getSize ());
593+ browser .setVisible (false );
594+ }
595+
574596@ Override
575597public void create (Composite parent , int style ) {
576598 createInstance (0 );
@@ -587,21 +609,13 @@ private void createInstance(int previousAttempts) {
587609}
588610
589611private IUnknown createControllerInitializationCallback (int previousAttempts ) {
590- Runnable initializationRollback = () -> {
591- webViewProvider .abortInitialization ();
592- if (environment2 != null ) {
593- environment2 .Release ();
594- environment2 = null ;
595- }
596- containingEnvironment .instances ().remove (this );
597- };
598612 return newCallback ((result , pv ) -> {
599613 if (browser .isDisposed ()) {
600- initializationRollback . run ();
614+ rollbackInitialization ();
601615 return COM .S_OK ;
602616 }
603617 if (result == OS .HRESULT_FROM_WIN32 (OS .ERROR_INVALID_STATE )) {
604- initializationRollback . run ();
618+ rollbackInitialization ();
605619 SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
606620 " Edge instance with same data folder but different environment options already exists" );
607621 }
@@ -611,14 +625,14 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
611625 setupBrowser ((int ) result , pv );
612626 break ;
613627 case COM .E_WRONG_THREAD :
614- initializationRollback . run ();
628+ rollbackInitialization ();
615629 error (SWT .ERROR_THREAD_INVALID_ACCESS , (int ) result );
616630 break ;
617631 case COM .E_ABORT :
618- initializationRollback . run ();
632+ rollbackInitialization ();
619633 break ;
620634 default :
621- initializationRollback . run ();
635+ rollbackInitialization ();
622636 if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
623637 System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
624638 createInstance (previousAttempts + 1 );
@@ -632,6 +646,19 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
632646 });
633647}
634648
649+ private void rollbackInitialization () {
650+ webViewProvider .abortInitialization ();
651+ releaseEnvironment ();
652+ }
653+
654+ private void releaseEnvironment () {
655+ if (environment2 != null ) {
656+ environment2 .Release ();
657+ environment2 = null ;
658+ }
659+ containingEnvironment .instances ().remove (this );
660+ }
661+
635662void setupBrowser (int hr , long pv ) {
636663 long [] ppv = new long [] {pv };
637664 controller = new ICoreWebView2Controller (ppv [0 ]);
0 commit comments