44import '../../extensions' ;
55
66import * as path from 'path' ;
7- import { Uri , Webview , WebviewOptions , WebviewPanel , window } from 'vscode' ;
7+ import { Event , EventEmitter , Uri , Webview , WebviewOptions , WebviewPanel , window } from 'vscode' ;
88import { Identifiers } from '../../../datascience/constants' ;
9+ import { traceError } from '../../logger' ;
910import { IFileSystem } from '../../platform/types' ;
1011import { IDisposableRegistry } from '../../types' ;
1112import * as localize from '../../utils/localize' ;
@@ -14,6 +15,7 @@ import { IWebPanel, IWebPanelOptions, WebPanelMessage } from '../types';
1415export class WebPanel implements IWebPanel {
1516 private panel : WebviewPanel | undefined ;
1617 private loadPromise : Promise < void > ;
18+ private loadFailedEmitter = new EventEmitter < void > ( ) ;
1719
1820 constructor (
1921 private fs : IFileSystem ,
@@ -43,6 +45,9 @@ export class WebPanel implements IWebPanel {
4345 this . loadPromise = this . load ( ) ;
4446 }
4547
48+ public get loadFailed ( ) : Event < void > {
49+ return this . loadFailedEmitter . event ;
50+ }
4651 public async show ( preserveFocus : boolean ) {
4752 await this . loadPromise ;
4853 if ( this . panel ) {
@@ -89,42 +94,49 @@ export class WebPanel implements IWebPanel {
8994
9095 // tslint:disable-next-line:no-any
9196 private async load ( ) {
92- if ( this . panel ) {
93- const localFilesExist = await Promise . all ( this . options . scripts . map ( ( s ) => this . fs . fileExists ( s ) ) ) ;
94- if ( localFilesExist . every ( ( exists ) => exists === true ) ) {
95- // Call our special function that sticks this script inside of an html page
96- // and translates all of the paths to vscode-resource URIs
97- this . panel . webview . html = await this . generateLocalReactHtml ( this . panel . webview ) ;
98-
99- // Reset when the current panel is closed
100- this . disposableRegistry . push (
101- this . panel . onDidDispose ( ( ) => {
102- this . panel = undefined ;
103- this . options . listener . dispose ( ) . ignoreErrors ( ) ;
104- } )
105- ) ;
106-
107- this . disposableRegistry . push (
108- this . panel . webview . onDidReceiveMessage ( ( message ) => {
109- // Pass the message onto our listener
110- this . options . listener . onMessage ( message . type , message . payload ) ;
111- } )
112- ) ;
113-
114- this . disposableRegistry . push (
115- this . panel . onDidChangeViewState ( ( _e ) => {
116- // Pass the state change onto our listener
117- this . options . listener . onChangeViewState ( this ) ;
118- } )
119- ) ;
120-
121- // Set initial state
122- this . options . listener . onChangeViewState ( this ) ;
123- } else {
124- // Indicate that we can't load the file path
125- const badPanelString = localize . DataScience . badWebPanelFormatString ( ) ;
126- this . panel . webview . html = badPanelString . format ( this . options . scripts . join ( ', ' ) ) ;
97+ try {
98+ if ( this . panel ) {
99+ const localFilesExist = await Promise . all ( this . options . scripts . map ( ( s ) => this . fs . fileExists ( s ) ) ) ;
100+ if ( localFilesExist . every ( ( exists ) => exists === true ) ) {
101+ // Call our special function that sticks this script inside of an html page
102+ // and translates all of the paths to vscode-resource URIs
103+ this . panel . webview . html = await this . generateLocalReactHtml ( this . panel . webview ) ;
104+
105+ // Reset when the current panel is closed
106+ this . disposableRegistry . push (
107+ this . panel . onDidDispose ( ( ) => {
108+ this . panel = undefined ;
109+ this . options . listener . dispose ( ) . ignoreErrors ( ) ;
110+ } )
111+ ) ;
112+
113+ this . disposableRegistry . push (
114+ this . panel . webview . onDidReceiveMessage ( ( message ) => {
115+ // Pass the message onto our listener
116+ this . options . listener . onMessage ( message . type , message . payload ) ;
117+ } )
118+ ) ;
119+
120+ this . disposableRegistry . push (
121+ this . panel . onDidChangeViewState ( ( _e ) => {
122+ // Pass the state change onto our listener
123+ this . options . listener . onChangeViewState ( this ) ;
124+ } )
125+ ) ;
126+
127+ // Set initial state
128+ this . options . listener . onChangeViewState ( this ) ;
129+ } else {
130+ // Indicate that we can't load the file path
131+ const badPanelString = localize . DataScience . badWebPanelFormatString ( ) ;
132+ this . panel . webview . html = badPanelString . format ( this . options . scripts . join ( ', ' ) ) ;
133+ }
127134 }
135+ } catch ( error ) {
136+ // If our web panel failes to load, report that out so whatever
137+ // is hosting the panel can clean up
138+ traceError ( `Error Loading WebPanel: ${ error } ` ) ;
139+ this . loadFailedEmitter . fire ( ) ;
128140 }
129141 }
130142
0 commit comments