Skip to content

Commit 26a1db3

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
ATL-1137: Show error when could not connect to CLI
Signed-off-by: Akos Kitta <[email protected]>
1 parent a3f7b79 commit 26a1db3

File tree

6 files changed

+39
-41
lines changed

6 files changed

+39
-41
lines changed

Diff for: .vscode/launch.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
"NODE_PRESERVE_SYMLINKS": "1"
3030
}
3131
},
32-
"program": "${workspaceRoot}/electron-app/src-gen/frontend/electron-main.js",
32+
"cwd": "${workspaceFolder}/electron-app",
3333
"protocol": "inspector",
3434
"args": [
35+
".",
3536
"--log-level=debug",
3637
"--hostname=localhost",
3738
"--no-cluster",

Diff for: arduino-ide-extension/src/browser/theia/workspace/workspace-service.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MessageService } from '@theia/core/lib/common/message-service';
66
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
77
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
88
import { FocusTracker, Widget } from '@theia/core/lib/browser';
9+
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
910
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
1011
import { ConfigService } from '../../../common/protocol/config-service';
1112
import { SketchesService, Sketch, SketchContainer } from '../../../common/protocol/sketches-service';
@@ -29,10 +30,15 @@ export class WorkspaceService extends TheiaWorkspaceService {
2930
@inject(ApplicationServer)
3031
protected readonly applicationServer: ApplicationServer;
3132

33+
@inject(FrontendApplicationStateService)
34+
protected readonly appStateService: FrontendApplicationStateService;
35+
36+
private application: FrontendApplication;
3237
private workspaceUri?: Promise<string | undefined>;
33-
private version?: string
38+
private version?: string;
3439

3540
async onStart(application: FrontendApplication): Promise<void> {
41+
this.application = application;
3642
const info = await this.applicationServer.getApplicationInfo();
3743
this.version = info?.version;
3844
application.shell.onDidChangeCurrentWidget(this.onCurrentWidgetChange.bind(this));
@@ -62,11 +68,12 @@ export class WorkspaceService extends TheiaWorkspaceService {
6268
}
6369
return (await this.sketchService.createNewSketch()).uri;
6470
} catch (err) {
71+
this.appStateService.reachedState('ready').then(() => this.application.shell.update());
6572
this.logger.fatal(`Failed to determine the sketch directory: ${err}`)
6673
this.messageService.error(
6774
'There was an error creating the sketch directory. ' +
6875
'See the log for more details. ' +
69-
'The application will probably not work as expected.')
76+
'The application will probably not work as expected.');
7077
return super.getDefaultWorkspaceUri();
7178
}
7279
})();

Diff for: arduino-ide-extension/src/node/board-discovery.ts

+2-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { injectable, inject, postConstruct, named } from 'inversify';
22
import { ClientDuplexStream } from '@grpc/grpc-js';
33
import { ILogger } from '@theia/core/lib/common/logger';
44
import { deepClone } from '@theia/core/lib/common/objects';
5-
import { CoreClientProvider } from './core-client-provider';
5+
import { CoreClientAware } from './core-client-provider';
66
import { BoardListWatchReq, BoardListWatchResp } from './cli-protocol/commands/board_pb';
77
import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsChangeEvent } from '../common/protocol';
88

@@ -12,15 +12,12 @@ import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsC
1212
* Unlike other services, this is not connection scoped.
1313
*/
1414
@injectable()
15-
export class BoardDiscovery {
15+
export class BoardDiscovery extends CoreClientAware {
1616

1717
@inject(ILogger)
1818
@named('discovery')
1919
protected discoveryLogger: ILogger;
2020

21-
@inject(CoreClientProvider)
22-
protected readonly coreClientProvider: CoreClientProvider;
23-
2421
@inject(NotificationServiceServer)
2522
protected readonly notificationService: NotificationServiceServer;
2623

@@ -133,23 +130,4 @@ export class BoardDiscovery {
133130
return availablePorts;
134131
}
135132

136-
private async coreClient(): Promise<CoreClientProvider.Client> {
137-
const coreClient = await new Promise<CoreClientProvider.Client>(async resolve => {
138-
const client = await this.coreClientProvider.client();
139-
if (client) {
140-
resolve(client);
141-
return;
142-
}
143-
const toDispose = this.coreClientProvider.onClientReady(async () => {
144-
const client = await this.coreClientProvider.client();
145-
if (client) {
146-
toDispose.dispose();
147-
resolve(client);
148-
return;
149-
}
150-
});
151-
});
152-
return coreClient;
153-
}
154-
155133
}

Diff for: arduino-ide-extension/src/node/core-client-provider.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as grpc from '@grpc/grpc-js';
22
import { inject, injectable } from 'inversify';
33
import { Event, Emitter } from '@theia/core/lib/common/event';
4+
import { DisposableCollection } from '@theia/core/lib/common/disposable';
45
import { GrpcClientProvider } from './grpc-client-provider';
56
import { ArduinoCoreClient } from './cli-protocol/commands/commands_grpc_pb';
67
import * as commandsGrpcPb from './cli-protocol/commands/commands_grpc_pb';
@@ -27,7 +28,7 @@ export class CoreClientProvider extends GrpcClientProvider<CoreClientProvider.Cl
2728
protected async reconcileClient(port: string | undefined): Promise<void> {
2829
if (port && port === this._port) {
2930
// No need to create a new gRPC client, but we have to update the indexes.
30-
if (this._client) {
31+
if (this._client && !(this._client instanceof Error)) {
3132
await this.updateIndexes(this._client);
3233
this.onClientReadyEmitter.fire();
3334
}
@@ -48,7 +49,7 @@ export class CoreClientProvider extends GrpcClientProvider<CoreClientProvider.Cl
4849
let resp: InitResp | undefined = undefined;
4950
const stream = client.init(initReq);
5051
stream.on('data', (data: InitResp) => resp = data);
51-
stream.on('end', () => resolve(resp));
52+
stream.on('end', () => resolve(resp!));
5253
stream.on('error', err => reject(err));
5354
});
5455

@@ -175,20 +176,27 @@ export abstract class CoreClientAware {
175176
protected readonly coreClientProvider: CoreClientProvider;
176177

177178
protected async coreClient(): Promise<CoreClientProvider.Client> {
178-
const coreClient = await new Promise<CoreClientProvider.Client>(async resolve => {
179+
const coreClient = await new Promise<CoreClientProvider.Client>(async (resolve, reject) => {
180+
const handle = (c: CoreClientProvider.Client | Error) => {
181+
if (c instanceof Error) {
182+
reject(c);
183+
} else {
184+
resolve(c);
185+
}
186+
}
179187
const client = await this.coreClientProvider.client();
180188
if (client) {
181-
resolve(client);
189+
handle(client);
182190
return;
183191
}
184-
const toDispose = this.coreClientProvider.onClientReady(async () => {
192+
const toDispose = new DisposableCollection();
193+
toDispose.push(this.coreClientProvider.onClientReady(async () => {
185194
const client = await this.coreClientProvider.client();
186195
if (client) {
187-
toDispose.dispose();
188-
resolve(client);
189-
return;
196+
handle(client);
190197
}
191-
});
198+
toDispose.dispose();
199+
}));
192200
});
193201
return coreClient;
194202
}

Diff for: arduino-ide-extension/src/node/grpc-client-provider.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export abstract class GrpcClientProvider<C> {
1717
protected readonly configService: ConfigServiceImpl;
1818

1919
protected _port: string | number | undefined;
20-
protected _client: C | undefined;
20+
protected _client: C | Error | undefined;
2121

2222
@postConstruct()
2323
protected init(): void {
@@ -28,20 +28,20 @@ export abstract class GrpcClientProvider<C> {
2828
this.configService.onConfigChange(updateClient);
2929
this.daemon.ready.then(updateClient);
3030
this.daemon.onDaemonStopped(() => {
31-
if (this._client) {
31+
if (this._client && !(this._client instanceof Error)) {
3232
this.close(this._client);
3333
}
3434
this._client = undefined;
3535
this._port = undefined;
3636
})
3737
}
3838

39-
async client(): Promise<C | undefined> {
39+
async client(): Promise<C | Error | undefined> {
4040
try {
4141
await this.daemon.ready;
4242
return this._client;
4343
} catch (error) {
44-
return undefined;
44+
return error;
4545
}
4646
}
4747

@@ -50,7 +50,7 @@ export abstract class GrpcClientProvider<C> {
5050
return; // Nothing to do.
5151
}
5252
this._port = port;
53-
if (this._client) {
53+
if (this._client && !(this._client instanceof Error)) {
5454
this.close(this._client);
5555
this._client = undefined;
5656
}
@@ -60,6 +60,7 @@ export abstract class GrpcClientProvider<C> {
6060
this._client = client;
6161
} catch (error) {
6262
this.logger.error('Could not create client for gRPC.', error)
63+
this._client = error;
6364
}
6465
}
6566
}

Diff for: arduino-ide-extension/src/node/monitor/monitor-service-impl.ts

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ export class MonitorServiceImpl implements MonitorService {
7272
if (!client) {
7373
return Status.NOT_CONNECTED;
7474
}
75+
if (client instanceof Error) {
76+
return { message: client.message };
77+
}
7578
const duplex = client.streamingOpen();
7679
this.connection = { duplex, config };
7780

0 commit comments

Comments
 (0)