From b2e7c41d64a6dc419f1a5dffd53ee66d8cd841d0 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 28 Sep 2020 15:45:23 -0700 Subject: [PATCH] notebooks: show a more friendly error if preloads fail Fixes https://github.com/microsoft/vscode/issues/105946 --- .../view/renderers/backLayerWebView.ts | 35 ++++++++----------- .../browser/view/renderers/webviewPreloads.ts | 26 ++++++++++---- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index c210fc526d0..8cc06b08600 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -148,7 +148,8 @@ export interface IFocusOutputMessage { } export interface IPreloadResource { - uri: string + originalUri: string; + uri: string; } export interface IUpdatePreloadResourceMessage { @@ -800,19 +801,15 @@ var requirejs = (function() { await this._loaded; const resources: IPreloadResource[] = []; - preloads = preloads.map(preload => { - if (this.environmentService.isExtensionDevelopment && (preload.scheme === 'http' || preload.scheme === 'https')) { - return preload; - } - return asWebviewUri(this.environmentService, this.id, preload); - }); + for (const preload of preloads) { + const uri = this.environmentService.isExtensionDevelopment && (preload.scheme === 'http' || preload.scheme === 'https') + ? preload : asWebviewUri(this.environmentService, this.id, preload); - preloads.forEach(e => { - if (!this._preloadsCache.has(e.toString())) { - resources.push({ uri: e.toString() }); - this._preloadsCache.add(e.toString()); + if (!this._preloadsCache.has(uri.toString())) { + resources.push({ uri: uri.toString(), originalUri: preload.toString() }); + this._preloadsCache.add(uri.toString()); } - }); + } if (!resources.length) { return; @@ -833,19 +830,17 @@ var requirejs = (function() { const resources: IPreloadResource[] = []; const extensionLocations: URI[] = []; for (const rendererInfo of renderers) { - const preloads = [rendererInfo.entrypoint, ...rendererInfo.preloads] - .map(preload => asWebviewUri(this.environmentService, this.id, preload)); extensionLocations.push(rendererInfo.extensionLocation); - - preloads.forEach(e => { - const resource: IPreloadResource = { uri: e.toString() }; + for (const preload of [rendererInfo.entrypoint, ...rendererInfo.preloads]) { + const uri = asWebviewUri(this.environmentService, this.id, preload); + const resource: IPreloadResource = { uri: uri.toString(), originalUri: preload.toString() }; requiredPreloads.push(resource); - if (!this._preloadsCache.has(e.toString())) { + if (!this._preloadsCache.has(uri.toString())) { resources.push(resource); - this._preloadsCache.add(e.toString()); + this._preloadsCache.add(uri.toString()); } - }); + } } if (!resources.length) { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 4355e350a66..7ff3a7e8e73 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -308,7 +308,7 @@ function webviewPreloads() { * Map of preload resource URIs to promises that resolve one the resource * loads or errors. */ - const preloadPromises = new Map>(); + const preloadPromises = new Map>(); const queuedOuputActions = new Map>(); /** @@ -341,7 +341,7 @@ function webviewPreloads() { switch (event.data.type) { case 'html': enqueueOutputAction(event.data, async data => { - await Promise.all(data.requiredPreloads.map(p => preloadPromises.get(p.uri))); + const preloadErrs = await Promise.all(data.requiredPreloads.map(p => preloadPromises.get(p.uri))); if (!queuedOuputActions.has(data.outputId)) { // output was cleared while loading return; } @@ -378,6 +378,18 @@ function webviewPreloads() { outputNode.innerHTML = content.htmlContent; cellOutputContainer.appendChild(outputNode); domEval(outputNode); + } else if (preloadErrs.some(e => !!e)) { + outputNode.innerText = `Error loading preloads:`; + const errList = document.createElement('ul'); + for (const err of preloadErrs) { + if (err) { + const item = document.createElement('li'); + item.innerText = err; + errList.appendChild(item); + } + } + outputNode.appendChild(errList); + cellOutputContainer.appendChild(outputNode); } else { onDidCreateOutput.fire([data.apiNamespace, { element: outputNode, @@ -465,13 +477,15 @@ function webviewPreloads() { const resources = event.data.resources; const preloadsContainer = document.getElementById('__vscode_preloads')!; for (let i = 0; i < resources.length; i++) { - const { uri } = resources[i]; + const { uri, originalUri } = resources[i]; const scriptTag = document.createElement('script'); scriptTag.setAttribute('src', uri); preloadsContainer.appendChild(scriptTag); - preloadPromises.set(uri, new Promise(resolve => { - scriptTag.addEventListener('load', () => resolve()); - scriptTag.addEventListener('error', () => resolve()); + preloadPromises.set(uri, new Promise(resolve => { + scriptTag.addEventListener('load', () => resolve(undefined)); + scriptTag.addEventListener('error', () => + resolve(`Network error loading ${originalUri}, does the path exist?`) + ); })); } break;