Skip to content

Commit 6eea3bf

Browse files
authored
Merge pull request #59 from DeepCodeAI/add_blocking_icon
Added blocking icon and fixed post-merge issues.
2 parents 5aa49c6 + e4eb625 commit 6eea3bf

12 files changed

Lines changed: 95 additions & 23 deletions

File tree

src/deepcode/DeepCodeExtension.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class DeepCodeExtension extends DeepCodeLib implements DeepCode.ExtensionInterfa
3333
try {
3434
await fn(...args);
3535
} catch (error) {
36-
this.processError(error, {
36+
await this.processError(error, {
3737
message: errorsLogs.command(name),
3838
});
3939
}
@@ -58,6 +58,7 @@ class DeepCodeExtension extends DeepCodeLib implements DeepCode.ExtensionInterfa
5858
DEEPCODE_OPEN_LOCAL,
5959
(path: vscode.Uri, range?: vscode.Range) => {
6060
vscode.window.showTextDocument(path, { selection: range }).then(
61+
// no need to wait for processError since then is called asynchronously as well
6162
() => {}, (err) => this.processError(err, {
6263
message: errorsLogs.command(DEEPCODE_OPEN_LOCAL),
6364
})
@@ -102,7 +103,11 @@ class DeepCodeExtension extends DeepCodeLib implements DeepCode.ExtensionInterfa
102103
context.subscriptions.push(
103104
vscode.commands.registerCommand(
104105
DEEPCODE_SETMODE_COMMAND,
105-
this.setMode.bind(this)
106+
this.executeCommand.bind(
107+
this,
108+
DEEPCODE_SETMODE_COMMAND,
109+
this.setMode.bind(this)
110+
)
106111
)
107112
);
108113

@@ -120,7 +125,11 @@ class DeepCodeExtension extends DeepCodeLib implements DeepCode.ExtensionInterfa
120125
context.subscriptions.push(
121126
vscode.commands.registerCommand(
122127
DEEPCODE_DCIGNORE_COMMAND,
123-
createDCIgnoreCommand
128+
this.executeCommand.bind(
129+
this,
130+
DEEPCODE_DCIGNORE_COMMAND,
131+
createDCIgnoreCommand
132+
)
124133
)
125134
);
126135

src/deepcode/constants/general.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ export const EXECUTION_DEBOUNCE_INTERVAL = 1000; // 1 second
88
export const EXECUTION_THROTTLING_INTERVAL = 1000 * 10;// * 60 * 30; // 30 minutes
99
export const EXECUTION_PAUSE_INTERVAL = 1000 * 60 * 30; // 30 minutes
1010
export const REFRESH_VIEW_DEBOUNCE_INTERVAL = 200; // 200 milliseconds
11+
// If CONNECTION_ERROR_RETRY_INTERVAL is smaller than EXECUTION_DEBOUNCE_INTERVAL it might get swallowed by the debouncer
12+
export const CONNECTION_ERROR_RETRY_INTERVAL = EXECUTION_DEBOUNCE_INTERVAL * 2 + 1000 * 3;

src/deepcode/constants/views.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
export const DEEPCODE_VIEW_SUPPORT = "deepcode.views.support";
1+
export const DEEPCODE_VIEW_ERROR = "deepcode.views.error";
2+
export const DEEPCODE_VIEW_WELCOME = "deepcode.views.welcome";
3+
export const DEEPCODE_VIEW_TC = "deepcode.views.tc";
4+
export const DEEPCODE_VIEW_EMPTY = "deepcode.views.empty";
25
export const DEEPCODE_VIEW_ANALYSIS = "deepcode.views.analysis";
6+
export const DEEPCODE_VIEW_SUPPORT = "deepcode.views.support";
7+
export const DEEPCODE_VIEW_ACTIONS = "deepcode.views.actions";
38

49
// Having multiple boolean contexts instead of a single context
510
// with multiple values helps us to avoid flickering UI.

src/deepcode/lib/analyzer/DeepCodeAnalyzer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class DeepCodeAnalyzer implements DeepCode.AnalyzerInterface {
219219
this.setIssuesMarkersDecoration();
220220
}
221221
} catch (err) {
222-
extension.processError(err, {
222+
await extension.processError(err, {
223223
message: errorsLogs.updateReviewPositions,
224224
bundleId: (extension.remoteBundles[updatedFile.workspace] || {}).bundleId,
225225
data: {

src/deepcode/lib/modules/BaseDeepCodeModule.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import DeepCodeWorkspaceFoldersWatcher from "../watchers/WorkspaceFoldersWatcher
88
import DeepCodeEditorsWatcher from "../watchers/EditorsWatcher";
99
import DeepCodeSettingsWatcher from "../watchers/DeepCodeSettingsWatcher";
1010
import { IDE_NAME, REFRESH_VIEW_DEBOUNCE_INTERVAL } from "../../constants/general";
11+
import { errorsLogs } from "../../messages/errorsServerLogMessages";
1112

1213
export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCodeModuleInterface {
1314
currentWorkspacePath: string;
@@ -26,6 +27,8 @@ export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCod
2627
refreshViewEmitter: vscode.EventEmitter<any>;
2728
analysisStatus = '';
2829
analysisProgress = 0;
30+
private progressBadgePromise: Promise<void> | undefined;
31+
private progressBadgeResolveFn: (() => void) | undefined;
2932

3033
// These attributes are used in tests
3134
staticToken = '';
@@ -89,6 +92,34 @@ export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCod
8992
return !!vscode.workspace.getConfiguration('deepcode').get<boolean>('yesTelemetry');
9093
}
9194

95+
private getProgressBadgePromise(): Promise<void> {
96+
if (this.progressBadgePromise === undefined) {
97+
// This should not be needed, but we resolve pending Promises
98+
// before overwriting the progressBadgeResolveFn reference.
99+
if (this.progressBadgeResolveFn) this.progressBadgeResolveFn();
100+
this.progressBadgePromise = new Promise(
101+
(resolve) => {
102+
this.progressBadgeResolveFn = resolve;
103+
}
104+
);
105+
}
106+
return this.progressBadgePromise;
107+
}
108+
109+
// Leave viewId undefined to remove the badge from all views
110+
async setLoadingBadge(viewId?: string): Promise<void> {
111+
if (viewId) {
112+
await vscode.window.withProgress(
113+
{ location: { viewId } },
114+
this.getProgressBadgePromise.bind(this)
115+
);
116+
} else {
117+
if (this.progressBadgeResolveFn) this.progressBadgeResolveFn();
118+
this.progressBadgePromise = undefined;
119+
this.progressBadgeResolveFn = undefined;
120+
}
121+
}
122+
92123
// Avoid refreshing context/views too often:
93124
// https://github.com/Microsoft/vscode/issues/68424
94125
refreshViews = _.debounce(

src/deepcode/lib/modules/BundlesModule.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ abstract class BundlesModule extends LoginModule
102102

103103
onError(error: Error) {
104104
this.terminateAnalysis();
105+
// no need to wait for processError since onError is called asynchronously as well
105106
this.processError(error, {
106107
message: errorsLogs.failedServiceAI,
107108
});
@@ -137,7 +138,7 @@ abstract class BundlesModule extends LoginModule
137138
try {
138139
this.serverFilesFilterList = await http.getFilters(this.baseURL, this.token);
139140
} catch (err) {
140-
this.processError(err, {
141+
await this.processError(err, {
141142
message: errorsLogs.filtersFiles
142143
})
143144
}
@@ -155,7 +156,7 @@ abstract class BundlesModule extends LoginModule
155156
if (!Object.keys(this.serverFilesFilterList).length) {
156157
await this.createFilesFilterList();
157158
if (!Object.keys(this.serverFilesFilterList).length) {
158-
this.processError(new Error(errorsLogs.filtersFiles), {
159+
await this.processError(new Error(errorsLogs.filtersFiles), {
159160
message: errorsLogs.filtersFiles,
160161
data: {
161162
filters: this.serverFilesFilterList
@@ -202,6 +203,7 @@ abstract class BundlesModule extends LoginModule
202203
});
203204

204205
http.analyse(this.baseURL, this.token, path, this.files, removedFiles).catch(
206+
// no need to wait for processError since catch is called asynchronously as well
205207
(error) => this.processError(error, {
206208
message: errorsLogs.analyse
207209
})

src/deepcode/lib/modules/DeepCodeLib.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default class DeepCodeLib extends BundlesModule implements DeepCode.DeepC
4444
private async executeExtensionPipeline(): Promise<void> {
4545
console.log("DeepCode: starting execution pipeline");
4646
await setContext(DEEPCODE_CONTEXT.ERROR, false);
47+
await this.setLoadingBadge();
4748

4849
const loggedIn = await this.checkSession();
4950
if (!loggedIn) return;
@@ -70,7 +71,7 @@ export default class DeepCodeLib extends BundlesModule implements DeepCode.DeepC
7071
try {
7172
await this.executeExtensionPipeline();
7273
} catch (err) {
73-
this.processError(err, {
74+
await this.processError(err, {
7475
message: errorsLogs.failedExecutionDebounce,
7576
});
7677
}
@@ -79,10 +80,10 @@ export default class DeepCodeLib extends BundlesModule implements DeepCode.DeepC
7980
{ 'leading': true }
8081
);
8182

82-
setMode(mode: string): void {
83+
async setMode(mode: string): Promise<void> {
8384
if (!Object.values(DEEPCODE_MODE_CODES).includes(mode)) return;
8485
this._mode = mode;
85-
setContext(DEEPCODE_CONTEXT.MODE, mode);
86+
await setContext(DEEPCODE_CONTEXT.MODE, mode);
8687
switch(mode) {
8788
case DEEPCODE_MODE_CODES.PAUSED:
8889
this._unpauseTimeout = setTimeout(this.unpause.bind(this), EXECUTION_PAUSE_INTERVAL);

src/deepcode/lib/modules/LoginModule.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import ReportModule from "./ReportModule";
22
import DeepCode from "../../../interfaces/DeepCodeInterfaces";
33
import http from "../../http/requests";
44
import { setContext, viewInBrowser } from "../../utils/vscodeCommandsUtils";
5-
import { DEEPCODE_CONTEXT } from "../../constants/views";
5+
import {
6+
DEEPCODE_VIEW_WELCOME,
7+
DEEPCODE_VIEW_TC,
8+
DEEPCODE_CONTEXT
9+
} from "../../constants/views";
610
import { errorsLogs } from "../../messages/errorsServerLogMessages";
711

812
const sleep = (duration: number) => new Promise(resolve => setTimeout(resolve, duration));
@@ -17,7 +21,8 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
1721

1822
this.pendingLogin = true;
1923
try {
20-
await setContext(DEEPCODE_CONTEXT.LOGGEDIN, false);
24+
const checkCurrentToken = await this.checkSession();
25+
if (checkCurrentToken) return;
2126
const result = await http.login(this.baseURL, this.source);
2227
const { sessionToken, loginURL } = result;
2328
if (!sessionToken || !loginURL) {
@@ -40,8 +45,9 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
4045
if (this.token) {
4146
try {
4247
validSession = !!(await http.checkSession(this.baseURL, this.token));
48+
if (!validSession) await this.setLoadingBadge(DEEPCODE_VIEW_WELCOME);
4349
} catch (err) {
44-
this.processError(err, {
50+
await this.processError(err, {
4551
message: errorsLogs.loginStatus
4652
});
4753
}
@@ -66,11 +72,13 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
6672
async checkApproval(): Promise<boolean> {
6773
const approved = this.uploadApproved;
6874
await setContext(DEEPCODE_CONTEXT.APPROVED, approved);
75+
if (!approved) await this.setLoadingBadge(DEEPCODE_VIEW_TC);
6976
return approved;
7077
}
7178

7279
async approveUpload(): Promise<void> {
7380
await this.setUploadApproved(true);
81+
await this.setLoadingBadge();
7482
await this.checkApproval();
7583
}
7684

src/deepcode/lib/modules/ReportModule.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import BaseDeepCodeModule from "./BaseDeepCodeModule";
44
import { statusCodes } from "../../constants/statusCodes";
55
import { errorsLogs } from "../../messages/errorsServerLogMessages";
66
import { setContext } from "../../utils/vscodeCommandsUtils";
7-
import { DEEPCODE_CONTEXT, DEEPCODE_ERROR_CODES } from "../../constants/views";
8-
import { MAX_CONNECTION_RETRIES } from "../../constants/general";
7+
import { DEEPCODE_CONTEXT, DEEPCODE_ERROR_CODES, DEEPCODE_VIEW_ERROR } from "../../constants/views";
8+
import { MAX_CONNECTION_RETRIES, CONNECTION_ERROR_RETRY_INTERVAL } from "../../constants/general";
99

1010
abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.ReportModuleInterface {
1111
private transientErrors = 0;
@@ -45,7 +45,7 @@ abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.Repor
4545
...options
4646
});
4747
} catch(error) {
48-
this.processError(error, {
48+
await this.processError(error, {
4949
message: errorsLogs.sendEvent,
5050
data: {
5151
event,
@@ -60,6 +60,17 @@ abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.Repor
6060
async processError(
6161
error: DeepCode.errorType,
6262
options: { [key: string]: any } = {}
63+
): Promise<void> {
64+
// We don't want to have unhandled rejections around, so if it
65+
// happens in the error handler we just log it to console.error
66+
return this.processErrorInternal(error, options).catch((error) =>
67+
console.error("DeepCode error handler failed with error:", error)
68+
);
69+
}
70+
71+
private async processErrorInternal(
72+
error: DeepCode.errorType,
73+
options: { [key: string]: any } = {}
6374
): Promise<void> {
6475
console.error("DeepCode error handler:", error);
6576

@@ -89,24 +100,25 @@ abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.Repor
89100
} = statusCodes;
90101

91102
switch (error.statusCode) {
92-
case unauthorizedContent:
93-
case unauthorizedBundleAccess:
94103
case serverError:
95104
case badGateway:
96105
case serviceUnavailable:
97106
case timeout:
98-
await this.connectionErrorHandler();
107+
return this.connectionErrorHandler();
108+
case unauthorizedContent:
109+
case unauthorizedBundleAccess:
99110
case unauthorizedUser:
100111
case notFound:
101112
default:
102113
await this.sendErrorToServer(error, options);
103-
await this.generalErrorHandler();
114+
return this.generalErrorHandler();
104115
}
105116
}
106117

107118
private async generalErrorHandler(): Promise<void> {
108119
this.transientErrors = 0;
109120
await setContext(DEEPCODE_CONTEXT.ERROR, DEEPCODE_ERROR_CODES.BLOCKING);
121+
await this.setLoadingBadge(DEEPCODE_VIEW_ERROR);
110122
}
111123

112124
private async connectionErrorHandler(): Promise<void> {
@@ -118,7 +130,7 @@ abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.Repor
118130
this.startExtension().catch((err) => this.processError(err, {
119131
message: errorsLogs.failedExecutionTransient,
120132
}));
121-
}, 5000);
133+
}, CONNECTION_ERROR_RETRY_INTERVAL);
122134
}
123135

124136
private async sendErrorToServer(

src/deepcode/messages/errorsServerLogMessages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ export const errorsLogs = {
2626
command: (type: string) => `Failed to execute ${type} command`,
2727
sendEvent: "Failed to send event to server",
2828
configWatcher: "Failed to handle configuration update",
29+
loadingBadge: "Failed to set loading badge icon on analysis view",
2930
};

0 commit comments

Comments
 (0)