Skip to content

Commit c631fdd

Browse files
[DECO-239] Catch login errors (#186)
- Catch errors when attaching deleted repo from project.json - Add a bunch of error logs. - Improve error logging formatting https://user-images.githubusercontent.com/88345179/200773372-998bb0bd-33ad-4d57-b440-7eeeab772906.mov
1 parent 0f33cbe commit c631fdd

4 files changed

Lines changed: 113 additions & 51 deletions

File tree

packages/databricks-sdk-js/src/logging/NamedLogger.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,16 @@ export class NamedLogger {
103103
}
104104

105105
error(message?: string, obj?: any) {
106-
this.log(LEVELS.error, message, obj);
106+
if (Object(obj) === obj) {
107+
obj = {
108+
...Object.getOwnPropertyNames(obj).reduce((acc, i) => {
109+
acc[i] = (obj as any)[i];
110+
return acc;
111+
}, {} as any),
112+
...(obj as any),
113+
};
114+
}
115+
this.log(LEVELS.error, message, {error: obj});
107116
}
108117

109118
withContext<T>({

packages/databricks-vscode/src/configuration/ConnectionManager.ts

Lines changed: 81 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {selectProfile} from "./selectProfileWizard";
2121
import {ClusterManager} from "../cluster/ClusterManager";
2222
import {workspace} from "@databricks/databricks-sdk";
2323
import {DatabricksWorkspace} from "./DatabricksWorkspace";
24+
import {NamedLogger} from "@databricks/databricks-sdk/dist/logging";
2425

2526
const extensionVersion = require("../../package.json").version;
2627

@@ -94,6 +95,18 @@ export class ConnectionManager {
9495
}
9596

9697
async login(interactive: boolean = false): Promise<void> {
98+
try {
99+
await this._login(interactive);
100+
} catch (e) {
101+
NamedLogger.getOrCreate("Extension").error("Login Error", e);
102+
if (interactive) {
103+
window.showErrorMessage(`Login error ${JSON.stringify(e)}`);
104+
}
105+
this.updateState("DISCONNECTED");
106+
await this.logout();
107+
}
108+
}
109+
private async _login(interactive: boolean = false): Promise<void> {
97110
await this.logout();
98111
this.updateState("CONNECTING");
99112

@@ -124,7 +137,7 @@ export class ConnectionManager {
124137
);
125138
} catch (e: any) {
126139
const message = `Can't login to Databricks: ${e.message}`;
127-
console.error(message);
140+
NamedLogger.getOrCreate("Extension").error(message, e);
128141
if (interactive) {
129142
window.showErrorMessage(message);
130143
}
@@ -146,7 +159,7 @@ export class ConnectionManager {
146159
message =
147160
"Files in Repos is not enabled for this workspace. Please enable it in the Databricks UI.";
148161
}
149-
console.error(message);
162+
NamedLogger.getOrCreate("Extension").error(message);
150163
if (interactive) {
151164
let result = await window.showWarningMessage(
152165
message,
@@ -230,7 +243,11 @@ export class ConnectionManager {
230243
profile
231244
);
232245
} catch (e: any) {
233-
console.error(e);
246+
NamedLogger.getOrCreate("Extension").error(
247+
`Connection with profile "${profile}" failed`,
248+
e
249+
);
250+
234251
const response = await window.showWarningMessage(
235252
`Connection with profile "${profile}" failed with error: "${e.message}"."`,
236253
"Retry",
@@ -277,24 +294,40 @@ export class ConnectionManager {
277294
cluster: Cluster | string,
278295
skipWrite = false
279296
): Promise<void> {
280-
if (this.cluster === cluster) {
281-
return;
282-
}
297+
try {
298+
if (this.cluster === cluster) {
299+
return;
300+
}
283301

284-
if (typeof cluster === "string") {
285-
cluster = await Cluster.fromClusterId(this._apiClient!, cluster);
286-
}
302+
if (typeof cluster === "string") {
303+
cluster = await Cluster.fromClusterId(
304+
this._apiClient!,
305+
cluster
306+
);
307+
}
287308

288-
if (!skipWrite) {
289-
this._projectConfigFile!.clusterId = cluster.id;
290-
await this._projectConfigFile!.write();
291-
}
309+
if (!skipWrite) {
310+
this._projectConfigFile!.clusterId = cluster.id;
311+
await this._projectConfigFile!.write();
312+
}
292313

293-
this.updateCluster(cluster);
314+
this.updateCluster(cluster);
315+
} catch (e) {
316+
NamedLogger.getOrCreate("Extension").error(
317+
"Attach Cluster error",
318+
e
319+
);
320+
window.showErrorMessage(
321+
`Error in attaching cluster destination ${
322+
typeof cluster === "string" ? cluster : cluster.id
323+
}`
324+
);
325+
await this.detachCluster();
326+
}
294327
}
295328

296329
async detachCluster(): Promise<void> {
297-
if (!this.cluster) {
330+
if (!this.cluster && this._projectConfigFile?.clusterId === undefined) {
298331
return;
299332
}
300333

@@ -310,32 +343,46 @@ export class ConnectionManager {
310343
workspacePath: Uri,
311344
skipWrite = false
312345
): Promise<void> {
313-
if (
314-
!vscodeWorkspace.workspaceFolders ||
315-
!vscodeWorkspace.workspaceFolders.length
316-
) {
317-
// TODO how do we handle this?
318-
return;
319-
}
346+
try {
347+
if (
348+
!vscodeWorkspace.workspaceFolders ||
349+
!vscodeWorkspace.workspaceFolders.length
350+
) {
351+
// TODO how do we handle this?
352+
return;
353+
}
320354

321-
if (!skipWrite) {
322-
this._projectConfigFile!.workspacePath = workspacePath.path;
323-
await this._projectConfigFile!.write();
324-
}
355+
if (!skipWrite) {
356+
this._projectConfigFile!.workspacePath = workspacePath.path;
357+
await this._projectConfigFile!.write();
358+
}
325359

326-
const wsUri = vscodeWorkspace.workspaceFolders[0].uri;
327-
if (this.apiClient === undefined) {
328-
throw new Error(
329-
"Can't attach a Repo when profile is not connected"
360+
const wsUri = vscodeWorkspace.workspaceFolders[0].uri;
361+
if (this.apiClient === undefined) {
362+
throw new Error(
363+
"Can't attach a Repo when profile is not connected"
364+
);
365+
}
366+
this.updateSyncDestination(
367+
await SyncDestination.from(this.apiClient, workspacePath, wsUri)
368+
);
369+
} catch (e) {
370+
NamedLogger.getOrCreate("Extension").error(
371+
"Attach Sync Destination error",
372+
e
373+
);
374+
window.showErrorMessage(
375+
`Error in attaching sync destination ${workspacePath.fsPath}`
330376
);
377+
await this.detachSyncDestination();
331378
}
332-
this.updateSyncDestination(
333-
await SyncDestination.from(this.apiClient, workspacePath, wsUri)
334-
);
335379
}
336380

337381
async detachSyncDestination(): Promise<void> {
338-
if (!this._syncDestination) {
382+
if (
383+
!this._syncDestination &&
384+
this._projectConfigFile?.workspacePath === undefined
385+
) {
339386
return;
340387
}
341388

packages/databricks-vscode/src/extension.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {showQuickStartOnFirstUse} from "./quickstart/QuickStart";
2525
import {PublicApi} from "@databricks/databricks-vscode-types";
2626
import {initLoggers} from "./logger";
2727
import {UtilsCommands} from "./utils/UtilsCommands";
28+
import {NamedLogger} from "@databricks/databricks-sdk/dist/logging";
2829

2930
export function activate(context: ExtensionContext): PublicApi | undefined {
3031
const a = workspace.workspaceFolders;
@@ -47,7 +48,6 @@ export function activate(context: ExtensionContext): PublicApi | undefined {
4748
let cli = new CliWrapper(context);
4849
// Configuration group
4950
let connectionManager = new ConnectionManager(cli);
50-
connectionManager.login(false);
5151

5252
const synchronizer = new CodeSynchronizer(connectionManager, cli);
5353
const clusterModel = new ClusterModel(connectionManager);
@@ -226,7 +226,9 @@ export function activate(context: ExtensionContext): PublicApi | undefined {
226226
)
227227
);
228228

229-
showQuickStartOnFirstUse(context);
229+
showQuickStartOnFirstUse(context).catch((e) => {
230+
NamedLogger.getOrCreate("Extension").error("Quick Start error", e);
231+
});
230232

231233
//utils
232234
const utilCommands = new UtilsCommands();
@@ -238,6 +240,10 @@ export function activate(context: ExtensionContext): PublicApi | undefined {
238240
)
239241
);
240242

243+
connectionManager.login(false).catch((e) => {
244+
NamedLogger.getOrCreate("Extension").error("Login error", e);
245+
});
246+
241247
return {
242248
connectionManager: connectionManager,
243249
};

packages/databricks-vscode/src/logger/outputConsoleTransport.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,26 @@ export function getOutputConsoleTransport(outputChannel: OutputChannel) {
5858
return new transports.Stream({
5959
format: format((info: any) => {
6060
const stripped = Object.assign({}, info) as any;
61-
if (stripped[LEVEL] === "error") {
62-
return info;
63-
}
6461
delete stripped[LEVEL];
6562
delete stripped[MESSAGE];
6663
delete stripped[SPLAT];
6764
delete stripped["level"];
6865
delete stripped["message"];
6966

70-
info[MESSAGE] = inspect(
71-
{
72-
...recursiveTruncate(
73-
stripped,
74-
workspaceConfigs.truncationDepth
75-
),
76-
timestamp: new Date().toLocaleString(),
77-
},
78-
false,
79-
workspaceConfigs.truncationDepth
80-
);
67+
info[MESSAGE] =
68+
info.level === "error"
69+
? inspect(stripped, false, 1000)
70+
: inspect(
71+
{
72+
...recursiveTruncate(
73+
stripped,
74+
workspaceConfigs.truncationDepth
75+
),
76+
timestamp: new Date().toLocaleString(),
77+
},
78+
false,
79+
workspaceConfigs.truncationDepth
80+
);
8181
return info;
8282
})(),
8383
stream: new OutputConsoleStream(outputChannel, {

0 commit comments

Comments
 (0)