@@ -298,8 +298,8 @@ class WebViewWrapper {
298
298
299
299
class WebViewProvider {
300
300
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 (() -> {});
303
303
304
304
ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
305
305
long [] ppv = new long [1 ];
@@ -316,10 +316,23 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
316
316
return webView ;
317
317
}
318
318
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
+
319
333
private void abortInitialization () {
320
334
webViewWrapperFuture .cancel (true );
321
335
}
322
-
323
336
private ICoreWebView2_2 initializeWebView_2 (ICoreWebView2 webView ) {
324
337
long [] ppv = new long [1 ];
325
338
int hr = webView .QueryInterface (COM .IID_ICoreWebView2_2 , ppv );
@@ -571,6 +584,15 @@ private String getDataDir(Display display) {
571
584
return dataDir ;
572
585
}
573
586
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
+
574
596
@ Override
575
597
public void create (Composite parent , int style ) {
576
598
createInstance (0 );
@@ -587,21 +609,13 @@ private void createInstance(int previousAttempts) {
587
609
}
588
610
589
611
private 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
- };
598
612
return newCallback ((result , pv ) -> {
599
613
if (browser .isDisposed ()) {
600
- initializationRollback . run ();
614
+ rollbackInitialization ();
601
615
return COM .S_OK ;
602
616
}
603
617
if (result == OS .HRESULT_FROM_WIN32 (OS .ERROR_INVALID_STATE )) {
604
- initializationRollback . run ();
618
+ rollbackInitialization ();
605
619
SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
606
620
" Edge instance with same data folder but different environment options already exists" );
607
621
}
@@ -611,14 +625,14 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
611
625
setupBrowser ((int ) result , pv );
612
626
break ;
613
627
case COM .E_WRONG_THREAD :
614
- initializationRollback . run ();
628
+ rollbackInitialization ();
615
629
error (SWT .ERROR_THREAD_INVALID_ACCESS , (int ) result );
616
630
break ;
617
631
case COM .E_ABORT :
618
- initializationRollback . run ();
632
+ rollbackInitialization ();
619
633
break ;
620
634
default :
621
- initializationRollback . run ();
635
+ rollbackInitialization ();
622
636
if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
623
637
System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
624
638
createInstance (previousAttempts + 1 );
@@ -632,6 +646,19 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
632
646
});
633
647
}
634
648
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
+
635
662
void setupBrowser (int hr , long pv ) {
636
663
long [] ppv = new long [] {pv };
637
664
controller = new ICoreWebView2Controller (ppv [0 ]);
0 commit comments