diff --git a/src/sql/workbench/services/connection/browser/cmsConnectionWidget.ts b/src/sql/workbench/services/connection/browser/cmsConnectionWidget.ts index 404fe9bd46..93b9c8cdc9 100644 --- a/src/sql/workbench/services/connection/browser/cmsConnectionWidget.ts +++ b/src/sql/workbench/services/connection/browser/cmsConnectionWidget.ts @@ -27,6 +27,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ConnectionWidget, AuthenticationType } from 'sql/workbench/services/connection/browser/connectionWidget'; +import { ILogService } from 'vs/platform/log/common/log'; /** * Connection Widget clas for CMS Connections @@ -48,10 +49,11 @@ export class CmsConnectionWidget extends ConnectionWidget { @ICapabilitiesService _capabilitiesService: ICapabilitiesService, @IClipboardService _clipboardService: IClipboardService, @IConfigurationService _configurationService: IConfigurationService, - @IAccountManagementService _accountManagementService: IAccountManagementService + @IAccountManagementService _accountManagementService: IAccountManagementService, + @ILogService _logService: ILogService, ) { super(options, callbacks, providerName, _themeService, _contextViewService, _connectionManagementService, _capabilitiesService, - _clipboardService, _configurationService, _accountManagementService); + _clipboardService, _configurationService, _accountManagementService, _logService); let authTypeOption = this._optionsMaps[ConnectionOptionSpecialType.authType]; if (authTypeOption) { if (OS === OperatingSystem.Windows) { @@ -135,7 +137,7 @@ export class CmsConnectionWidget extends ConnectionWidget { } DOM.addDisposableListener(container, 'paste', e => { - this._handleClipboard(); + this._handleClipboard().catch(err => this._logService.error(`Unexpected error parsing clipboard contents for CMS Connection Dialog ${err}`)); }); } diff --git a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts index 18b41438ed..949218a89c 100644 --- a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts +++ b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts @@ -323,12 +323,14 @@ export class ConnectionDialogWidget extends Modal { const controller = new RecentConnectionTreeController(leftClick, actionProvider, this._connectionManagementService, this._contextMenuService); actionProvider.onRecentConnectionRemoved(() => { const recentConnections: ConnectionProfile[] = this._connectionManagementService.getRecentConnections(); - this.open(recentConnections.length > 0); + this.open(recentConnections.length > 0).catch(err => this.logService.error(`Unexpected error opening connection widget after a recent connection was removed from action provider: ${err}`)); + // We're just using the connections to determine if there are connections to show, dispose them right after to clean up their handlers recentConnections.forEach(conn => conn.dispose()); }); controller.onRecentConnectionRemoved(() => { const recentConnections: ConnectionProfile[] = this._connectionManagementService.getRecentConnections(); - this.open(recentConnections.length > 0); + this.open(recentConnections.length > 0).catch(err => this.logService.error(`Unexpected error opening connection widget after a recent connection was removed from controller : ${err}`)); + // We're just using the connections to determine if there are connections to show, dispose them right after to clean up their handlers recentConnections.forEach(conn => conn.dispose()); }); this._recentConnectionTree = TreeCreationUtils.createConnectionTree(treeContainer, this._instantiationService, controller); @@ -399,7 +401,7 @@ export class ConnectionDialogWidget extends Modal { await TreeUpdateUtils.structuralTreeUpdate(this._recentConnectionTree, 'recent', this._connectionManagementService, this._providers); // reset saved connection tree - this._savedConnectionTree.setInput([]); + await this._savedConnectionTree.setInput([]); // call layout with view height this.layout(); diff --git a/src/sql/workbench/services/connection/browser/connectionWidget.ts b/src/sql/workbench/services/connection/browser/connectionWidget.ts index a29dd3a75b..5c44d942fb 100644 --- a/src/sql/workbench/services/connection/browser/connectionWidget.ts +++ b/src/sql/workbench/services/connection/browser/connectionWidget.ts @@ -34,6 +34,7 @@ import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import { endsWith, startsWith } from 'vs/base/common/strings'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ILogService } from 'vs/platform/log/common/log'; export class ConnectionWidget extends lifecycle.Disposable { private _previousGroupOption: string; @@ -100,7 +101,8 @@ export class ConnectionWidget extends lifecycle.Disposable { @ICapabilitiesService private _capabilitiesService: ICapabilitiesService, @IClipboardService private _clipboardService: IClipboardService, @IConfigurationService private _configurationService: IConfigurationService, - @IAccountManagementService private _accountManagementService: IAccountManagementService + @IAccountManagementService private _accountManagementService: IAccountManagementService, + @ILogService protected _logService: ILogService, ) { super(); this._callbacks = callbacks; @@ -135,7 +137,7 @@ export class ConnectionWidget extends lifecycle.Disposable { } DOM.addDisposableListener(container, 'paste', e => { - this._handleClipboard(); + this._handleClipboard().catch(err => this._logService.error(`Unexpected error parsing clipboard contents for connection widget : ${err}`)); }); } @@ -366,7 +368,7 @@ export class ConnectionWidget extends lifecycle.Disposable { if (this._azureAccountDropdown) { this._register(styler.attachSelectBoxStyler(this._azureAccountDropdown, this._themeService)); this._register(this._azureAccountDropdown.onDidSelect(() => { - this.onAzureAccountSelected(); + this.onAzureAccountSelected().catch(err => this._logService.error(`Unexpeted error handling Azure Account dropdown click : ${err}`)); })); } @@ -382,7 +384,7 @@ export class ConnectionWidget extends lifecycle.Disposable { let account = this._azureAccountList.find(account => account.key.accountId === this._azureAccountDropdown.value); if (account) { await this._accountManagementService.refreshAccount(account); - this.fillInAzureAccountOptions(); + await this.fillInAzureAccountOptions(); } })); } @@ -439,8 +441,11 @@ export class ConnectionWidget extends lifecycle.Disposable { } if (currentAuthType === AuthenticationType.AzureMFA) { - this.fillInAzureAccountOptions(); - this._azureAccountDropdown.enable(); + this.fillInAzureAccountOptions().then(() => { + // Don't enable the control until we've populated it + this._azureAccountDropdown.enable(); + }).catch(err => this._logService.error(`Unexpected error populating Azure Account dropdown : ${err}`)); + // Immediately show/hide appropriate elements though so user gets immediate feedback while we load accounts DOM.addClass(this._tableContainer, 'hide-username-password'); DOM.removeClass(this._tableContainer, 'hide-azure-accounts'); } else { @@ -464,7 +469,7 @@ export class ConnectionWidget extends lifecycle.Disposable { this._azureAccountDropdown.selectWithOptionName(oldSelection); } - private async updateRefreshCredentialsLink(): Promise { + private updateRefreshCredentialsLink(): void { let chosenAccount = this._azureAccountList.find(account => account.key.accountId === this._azureAccountDropdown.value); if (chosenAccount && chosenAccount.isStale) { DOM.removeClass(this._tableContainer, 'hide-refresh-link'); @@ -565,7 +570,7 @@ export class ConnectionWidget extends lifecycle.Disposable { } public focusOnOpen(): void { - this._handleClipboard(); + this._handleClipboard().catch(err => this._logService.error(`Unexpected error parsing clipboard contents for connection widget : ${err}`)); this._serverNameInputBox.focus(); this.focusPasswordIfNeeded(); this.clearValidationMessages(); @@ -640,7 +645,7 @@ export class ConnectionWidget extends lifecycle.Disposable { } this.onAzureTenantSelected(this._azureTenantDropdown.values.indexOf(this._azureTenantDropdown.value)); } - }); + }).catch(err => this._logService.error(`Unexpected error populating initial Azure Account options : ${err}`)); } // Disable connect button if -