Skip to content

Commit 062bc78

Browse files
authored
Show error notifications after failed environment setup (#1608)
## Changes Also change the setup logic slightly: we were re-checking the steps before taking an action, now we are doing it after the action. See comments in the code. Fixes #1601 ## Tests Existing tests and manually
1 parent 7252fe3 commit 062bc78

File tree

2 files changed

+56
-31
lines changed

2 files changed

+56
-31
lines changed

packages/databricks-vscode/src/language/EnvironmentCommands.ts

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {window, commands, QuickPickItem} from "vscode";
1+
import {window, commands, QuickPickItem, ProgressLocation} from "vscode";
22
import {FeatureManager} from "../feature-manager/FeatureManager";
33
import {MsPythonExtensionWrapper} from "./MsPythonExtensionWrapper";
44
import {Cluster} from "../sdk-extensions";
@@ -21,35 +21,56 @@ export class EnvironmentCommands {
2121
);
2222
}
2323

24+
private async checkEnvironmentDependencies() {
25+
return await window.withProgress(
26+
{
27+
location: ProgressLocation.Notification,
28+
title: `Databricks: checking python environment`,
29+
},
30+
() =>
31+
this.featureManager.isEnabled("environment.dependencies", true)
32+
);
33+
}
34+
2435
private async _setup(stepId?: string) {
25-
const state = await this.featureManager.isEnabled(
26-
"environment.dependencies",
27-
true
36+
// Get the state from the cache, we will re-check the state after taking an action (e.g. asking a user to select a venv or install dbconnect).
37+
let state = await this.featureManager.isEnabled(
38+
"environment.dependencies"
2839
);
29-
for (const [, step] of state.steps) {
30-
if (step.available || (stepId && step.id !== stepId)) {
31-
continue;
32-
}
33-
if (step.action) {
34-
return await step.action();
35-
} else if (step.message) {
36-
window.showErrorMessage(step.message);
37-
return false;
40+
for (const [, s] of state.steps) {
41+
if (!s.available && (!stepId || s.id === stepId) && s.action) {
42+
// Take an action of a failed step and re-check all steps state afterwards.
43+
// Re-checking is important to get the up to date `state.available` value.
44+
// It also fixes problems when Python extension doesn't notify us about the environment changes,
45+
// and we end up being stuck with the outdated UI warnings.
46+
await s.action();
47+
state = await this.checkEnvironmentDependencies();
48+
// All actions usually require user input (and can be cancelled), so here we stop after the first one
49+
// and let users re-run the setup based on the (updated) UI state in the Python Environment panel.
50+
break;
3851
}
3952
}
4053
if (state.available) {
4154
window.showInformationMessage(
4255
"Python environment and Databricks Connect are set up."
4356
);
44-
return true;
57+
} else {
58+
const detail = Array.from(state.steps.values())
59+
.filter(
60+
(s) => !s.available && !s.optional && (s.message || s.title)
61+
)
62+
.map((s) => s.message || s.title)
63+
.join("\n");
64+
window.showErrorMessage(
65+
`Failed to set up Python environment for Databricks Connect:\n${detail}`
66+
);
4567
}
4668
}
4769

4870
async refresh() {
4971
await window.withProgress(
5072
{location: {viewId: "configurationView"}},
51-
() =>
52-
this.featureManager.isEnabled("environment.dependencies", true)
73+
() => this.checkEnvironmentDependencies()
5374
);
5475
}
5576

packages/databricks-vscode/src/language/EnvironmentDependenciesVerifier.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export class EnvironmentDependenciesVerifier extends MultiStepAccessVerifier {
169169

170170
private getCurrentPythonVersionMessage(env?: ResolvedEnvironment): string {
171171
return env?.version && env.environment
172-
? `Current version is ${env.version.major}.${env.version.minor}.${env.version.micro}.`
172+
? `Current Python version is ${env.version.major}.${env.version.minor}.${env.version.micro}.`
173173
: "No active environments found.";
174174
}
175175

@@ -211,22 +211,26 @@ export class EnvironmentDependenciesVerifier extends MultiStepAccessVerifier {
211211

212212
async checkPythonEnvironment(): Promise<FeatureStepState> {
213213
try {
214-
const dbrVersionParts =
215-
this.connectionManager.cluster?.dbrVersion || [];
216-
const expectedPythonVersion =
217-
this.getExpectedPythonVersionMessage(dbrVersionParts);
218214
const env = await this.pythonExtension.pythonEnvironment;
219-
const envVersionTooLow =
215+
let envVersionTooLow =
220216
env?.version &&
221217
(env.version.major !== 3 || env.version.minor < 10);
222-
const noEnvironment = !env?.environment;
223-
const currentPythonVersionMessage =
224-
this.getCurrentPythonVersionMessage(env);
225-
if (noEnvironment || envVersionTooLow) {
218+
let dbrVersion = this.connectionManager.cluster?.dbrVersion || [];
219+
if (this.connectionManager.serverless) {
220+
dbrVersion = [15, 1];
221+
envVersionTooLow =
222+
env?.version &&
223+
(env.version.major !== 3 || env.version.minor < 11);
224+
}
225+
const expectedPythonVersion =
226+
this.getExpectedPythonVersionMessage(dbrVersion);
227+
if (!env?.environment || envVersionTooLow) {
226228
return this.rejectStep(
227229
"checkPythonEnvironment",
228230
`Activate an environment with Python ${expectedPythonVersion}`,
229-
`Databricks Connect requires ${expectedPythonVersion}. ${currentPythonVersionMessage}`,
231+
`Databricks Connect requires Python ${expectedPythonVersion}. ${this.getCurrentPythonVersionMessage(
232+
env
233+
)}`,
230234
this.selectPythonInterpreter.bind(this)
231235
);
232236
}
@@ -235,14 +239,14 @@ export class EnvironmentDependenciesVerifier extends MultiStepAccessVerifier {
235239
return this.rejectStep(
236240
"checkPythonEnvironment",
237241
`Activate an environment with Python ${expectedPythonVersion}`,
238-
"No python executable found",
242+
"No Python executable found.",
239243
this.selectPythonInterpreter.bind(this)
240244
);
241245
}
242246
const warning = this.getVersionMismatchWarning(
243-
dbrVersionParts[0],
247+
dbrVersion[0],
244248
env,
245-
currentPythonVersionMessage
249+
this.getCurrentPythonVersionMessage(env)
246250
);
247251
return this.acceptStep(
248252
"checkPythonEnvironment",
@@ -332,7 +336,7 @@ export class EnvironmentDependenciesVerifier extends MultiStepAccessVerifier {
332336
return this.rejectStep(
333337
"checkEnvironmentDependencies",
334338
"Install databricks-connect",
335-
"databricks-connect package is not installed in the current environment",
339+
"databricks-connect package is not installed in the current environment.",
336340
async (advertisement = false) =>
337341
this.installer.show(advertisement)
338342
);

0 commit comments

Comments
 (0)