Fix #4029 Ensure changeKernels always resolves, even in error states (#4488)

* Fix #4029 Ensure changeKernels always resolves, even in error states
This is necessary to unblock reverting the kernel on canceling  Python install
- startSession now correctly sets up kernel information, since a kernel is loaded there.
- Remove call to change kernel on session initialize. This isn't needed due to refactor
- Handle kernel change failure by attempting to fall back to old kernel
- ExtensionHost $startNewSession now ensures errors are sent across the wire.
- Update AttachTo and Kernel dropdowns so they handle kernel being available. This is needed since other changes mean the session is likely ready before these get going

* Fix to handle python cancel and load existing scenarios
- Made changes to handle failure flow when Python dialog is canceled
- Made changes to handle initial load fail. Kernel and Attach To dropdowns show No Kernel / None and you can choose a kernel
- Added error wrapping in ext host so that string errors make it across and aren't lost.
This commit is contained in:
Kevin Cunnane
2019-03-14 13:07:08 -07:00
committed by GitHub
parent 7973f0f178
commit 6f1a03587a
6 changed files with 164 additions and 105 deletions

View File

@@ -9,9 +9,9 @@
'use strict';
import { nb } from 'azdata';
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { localize } from 'vs/nls';
import { IClientSession, IKernelPreference, IClientSessionOptions } from './modelInterfaces';
import { Deferred } from 'sql/base/common/promise';
@@ -70,12 +70,14 @@ export class ClientSession implements IClientSession {
await this.initializeSession();
await this.updateCachedKernelSpec();
} catch (err) {
this._errorMessage = notebookUtils.getErrorMessage(err);
this._errorMessage = notebookUtils.getErrorMessage(err) || localize('clientSession.unknownError', "An error occurred while starting the notebook session");
}
// Always resolving for now. It's up to callers to check for error case
this._isReady = true;
this._ready.resolve();
this._kernelChangeCompleted.resolve();
if (!this.isInErrorState && this._session && this._session.kernel) {
await this.notifyKernelChanged(undefined, this._session.kernel);
}
}
private async startServer(): Promise<void> {
@@ -83,7 +85,7 @@ export class ClientSession implements IClientSession {
if (serverManager && !serverManager.isStarted) {
await serverManager.startServer();
if (!serverManager.isStarted) {
throw new Error(nls.localize('ServerNotStarted', 'Server did not start for unknown reason'));
throw new Error(localize('ServerNotStarted', "Server did not start for unknown reason"));
}
this.isServerStarted = serverManager.isStarted;
} else {
@@ -116,7 +118,7 @@ export class ClientSession implements IClientSession {
} catch (err) {
// TODO move registration
if (err && err.response && err.response.status === 501) {
this.options.notificationService.warn(nls.localize('kernelRequiresConnection', 'Kernel {0} was not found. The default kernel will be used instead.', kernelName));
this.options.notificationService.warn(localize('kernelRequiresConnection', "Kernel {0} was not found. The default kernel will be used instead.", kernelName));
session = await this.notebookManager.sessionManager.startNew({
path: this.notebookUri.fsPath,
kernelName: undefined
@@ -246,6 +248,11 @@ export class ClientSession implements IClientSession {
this._isReady = kernel.isReady;
await this.updateCachedKernelSpec();
// Send resolution events to listeners
await this.notifyKernelChanged(oldKernel, newKernel);
return kernel;
}
private async notifyKernelChanged(oldKernel: nb.IKernel, newKernel: nb.IKernel): Promise<void> {
let changeArgs: nb.IKernelChangedArgs = {
oldValue: oldKernel,
newValue: newKernel
@@ -255,7 +262,6 @@ export class ClientSession implements IClientSession {
// Wait on connection configuration to complete before resolving full kernel change
this._kernelChangeCompleted.resolve();
this._kernelChangedEmitter.fire(changeArgs);
return kernel;
}
private async updateCachedKernelSpec(): Promise<void> {