From d99989e17bc4174dba3e865954472d63df01ff1d Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Wed, 17 Mar 2021 10:01:33 -0700 Subject: [PATCH] Ignore load err that stops Python Ext from loading (#5146) --- .eslintrc.js | 1 - .../actions/create-venv-for-tests/action.yml | 1 - news/2 Fixes/5145.md | 1 + src/client/extension.ts | 37 +++++++++++++------ 4 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 news/2 Fixes/5145.md diff --git a/.eslintrc.js b/.eslintrc.js index 6e54fed55c1..d517ae989c6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -444,7 +444,6 @@ module.exports = { 'src/client/interpreter/display/progressDisplay.ts', 'src/client/interpreter/display/interpreterSelectionTip.ts', 'src/client/constants.ts', - 'src/client/extension.ts', 'src/client/extensionInit.ts', 'src/client/sourceMapSupport.ts', 'src/client/startupTelemetry.ts', diff --git a/.github/actions/create-venv-for-tests/action.yml b/.github/actions/create-venv-for-tests/action.yml index e4aa593b97d..fcf94fde492 100644 --- a/.github/actions/create-venv-for-tests/action.yml +++ b/.github/actions/create-venv-for-tests/action.yml @@ -32,6 +32,5 @@ runs: python -m ipykernel install --user --name .venvnokernel --display-name .venvnokernel python -m pip uninstall jedi --yes python -m pip install jedi==0.17.2 - python -m pip uninstall ipykernel --yes working-directory: src/test/datascience shell: bash diff --git a/news/2 Fixes/5145.md b/news/2 Fixes/5145.md new file mode 100644 index 00000000000..92749adcca2 --- /dev/null +++ b/news/2 Fixes/5145.md @@ -0,0 +1 @@ +Ensure extensions depending on Jupyter do not fail to load if Jupyter extension fails to load. diff --git a/src/client/extension.ts b/src/client/extension.ts index c915eefe0e2..122d520d043 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -36,6 +36,7 @@ import { activateComponents } from './extensionActivation'; import { initializeGlobals } from './extensionInit'; import { IServiceContainer } from './ioc/types'; import { sendErrorTelemetry, sendStartupTelemetry } from './startupTelemetry'; +import { noop } from './common/utils/misc'; durations.codeLoadingTime = stopWatch.elapsedTime; @@ -49,24 +50,36 @@ let activatedServiceContainer: IServiceContainer | undefined; // public functions export async function activate(context: IExtensionContext): Promise { - let api: IExtensionApi; - let ready: Promise; - let serviceContainer: IServiceContainer; try { + let api: IExtensionApi; + let ready: Promise; + let serviceContainer: IServiceContainer; [api, ready, serviceContainer] = await activateUnsafe(context, stopWatch, durations); + // Send the "success" telemetry only if activation did not fail. + // Otherwise Telemetry is send via the error handler. + sendStartupTelemetry(ready, durations, stopWatch, serviceContainer) + // Run in the background. + .ignoreErrors(); + await ready; + return api; } catch (ex) { // We want to completely handle the error // before notifying VS Code. await handleError(ex, durations); - throw ex; // re-raise + traceError('Failed to active the Jupyter Extension', ex); + // Disable this, as we don't want Python extension or any other extensions that depend on this to fall over. + // Return a dummy object, to ensure other extension do not fall over. + return { + createBlankNotebook: () => Promise.resolve(), + onKernelStateChange: () => ({ dispose: noop }), + ready: Promise.resolve(), + registerCellToolbarButton: () => ({ dispose: noop }), + registerNewNotebookContent: () => Promise.resolve(), + registerPythonApi: noop, + registerRemoteServerProvider: noop, + showDataViewer: () => Promise.resolve() + }; } - // Send the "success" telemetry only if activation did not fail. - // Otherwise Telemetry is send via the error handler. - sendStartupTelemetry(ready, durations, stopWatch, serviceContainer) - // Run in the background. - .ignoreErrors(); - await ready; - return api; } export function deactivate(): Thenable { @@ -114,7 +127,7 @@ async function activateUnsafe( // eslint-disable-next-line @typescript-eslint/no-explicit-any function displayProgress(promise: Promise) { const progressOptions: ProgressOptions = { location: ProgressLocation.Window, title: Common.loadingExtension() }; - window.withProgress(progressOptions, () => promise); + window.withProgress(progressOptions, () => promise).then(noop, noop); } /////////////////////////////