diff --git a/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim.ts b/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim.ts index 80a5de4cb3..a558375731 100644 --- a/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim.ts +++ b/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim.ts @@ -16,6 +16,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { generateUuid } from 'vs/base/common/uuid'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { TreeItemCollapsibleState } from 'vs/workbench/common/views'; +import { localize } from 'vs/nls'; export const SERVICE_ID = 'oeShimService'; export const IOEShimService = createDecorator(SERVICE_ID); @@ -44,45 +45,56 @@ export class OEShimService extends Disposable implements IOEShimService { } private async createSession(viewId: string, providerId: string, node: ITreeItem): Promise { - let deferred = new Deferred(); let connProfile = new ConnectionProfile(this.capabilities, node.payload); connProfile.saveProfile = false; if (this.cm.providerRegistered(providerId)) { - await new Promise(async (resolve, reject) => { - await this.cm.connect(connProfile, undefined, - { showConnectionDialogOnError: true, showFirewallRuleOnError: true, saveTheConnection: false, showDashboard: false, params: undefined }, - { - onConnectSuccess: async (e, profile) => { - let existingConnection = this.cm.findExistingConnection(profile); - connProfile = new ConnectionProfile(this.capabilities, await this.cm.addSavedPassword(existingConnection)); - resolve(); - }, - onConnectCanceled: () => { - reject('User canceled'); - }, - onConnectReject: undefined, - onConnectStart: undefined, - onDisconnect: undefined - }); - }); + connProfile = await this.connectOrPrompt(connProfile); + } else { + // Throw and expect upstream handler to notify about the error + // TODO: In the future should use extension recommendations to prompt for correct extension + throw new Error(localize('noProviderFound', "Cannot expand as the required connection provider '{0}' was not found", providerId)); } let sessionResp = await this.oe.createNewSession(providerId, connProfile); - let disp = this.oe.onUpdateObjectExplorerNodes(e => { - if (e.connection.id === connProfile.id) { - if (e.errorMessage) { - deferred.reject(); - return; + let sessionId = sessionResp.sessionId; + await new Promise((resolve, reject) => { + let listener = this.oe.onUpdateObjectExplorerNodes(e => { + if (e.connection.id === connProfile.id) { + if (e.errorMessage) { + listener.dispose(); + reject(new Error(e.errorMessage)); + return; + } + let rootNode = this.oe.getSession(sessionResp.sessionId).rootNode; + // this is how we know it was shimmed + if (rootNode.nodePath) { + this.nodeHandleMap.set(generateNodeMapKey(viewId, node), rootNode.nodePath); + } } - let rootNode = this.oe.getSession(sessionResp.sessionId).rootNode; - // this is how we know it was shimmed - if (rootNode.nodePath) { - this.nodeHandleMap.set(generateNodeMapKey(viewId, node), rootNode.nodePath); - } - } - disp.dispose(); - deferred.resolve(sessionResp.sessionId); + listener.dispose(); + resolve(sessionResp.sessionId); + }); }); - return deferred.promise; + return sessionId; + } + + private async connectOrPrompt(connProfile: ConnectionProfile): Promise { + connProfile = await new Promise(async (resolve, reject) => { + await this.cm.connect(connProfile, undefined, { showConnectionDialogOnError: true, showFirewallRuleOnError: true, saveTheConnection: false, showDashboard: false, params: undefined }, { + onConnectSuccess: async (e, profile) => { + let existingConnection = this.cm.findExistingConnection(profile); + connProfile = new ConnectionProfile(this.capabilities, existingConnection); + connProfile = await this.cm.addSavedPassword(connProfile); + resolve(connProfile); + }, + onConnectCanceled: () => { + reject(new Error(localize('loginCanceled', 'User canceled'))); + }, + onConnectReject: undefined, + onConnectStart: undefined, + onDisconnect: undefined + }); + }); + return connProfile; } public async disconnectNode(viewId: string, node: ITreeItem): Promise {