Skip to content

ATL-1137: Show error when could not connect to CLI #266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
"NODE_PRESERVE_SYMLINKS": "1"
}
},
"program": "${workspaceRoot}/electron-app/src-gen/frontend/electron-main.js",
"cwd": "${workspaceFolder}/electron-app",
"protocol": "inspector",
"args": [
".",
"--log-level=debug",
"--hostname=localhost",
"--no-cluster",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MessageService } from '@theia/core/lib/common/message-service';
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { FocusTracker, Widget } from '@theia/core/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { ConfigService } from '../../../common/protocol/config-service';
import { SketchesService, Sketch, SketchContainer } from '../../../common/protocol/sketches-service';
Expand All @@ -29,10 +30,15 @@ export class WorkspaceService extends TheiaWorkspaceService {
@inject(ApplicationServer)
protected readonly applicationServer: ApplicationServer;

@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;

private application: FrontendApplication;
private workspaceUri?: Promise<string | undefined>;
private version?: string
private version?: string;

async onStart(application: FrontendApplication): Promise<void> {
this.application = application;
const info = await this.applicationServer.getApplicationInfo();
this.version = info?.version;
application.shell.onDidChangeCurrentWidget(this.onCurrentWidgetChange.bind(this));
Expand Down Expand Up @@ -62,11 +68,12 @@ export class WorkspaceService extends TheiaWorkspaceService {
}
return (await this.sketchService.createNewSketch()).uri;
} catch (err) {
this.appStateService.reachedState('ready').then(() => this.application.shell.update());
this.logger.fatal(`Failed to determine the sketch directory: ${err}`)
this.messageService.error(
'There was an error creating the sketch directory. ' +
'See the log for more details. ' +
'The application will probably not work as expected.')
'The application will probably not work as expected.');
return super.getDefaultWorkspaceUri();
}
})();
Expand Down
26 changes: 2 additions & 24 deletions arduino-ide-extension/src/node/board-discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { injectable, inject, postConstruct, named } from 'inversify';
import { ClientDuplexStream } from '@grpc/grpc-js';
import { ILogger } from '@theia/core/lib/common/logger';
import { deepClone } from '@theia/core/lib/common/objects';
import { CoreClientProvider } from './core-client-provider';
import { CoreClientAware } from './core-client-provider';
import { BoardListWatchReq, BoardListWatchResp } from './cli-protocol/commands/board_pb';
import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsChangeEvent } from '../common/protocol';

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

@inject(ILogger)
@named('discovery')
protected discoveryLogger: ILogger;

@inject(CoreClientProvider)
protected readonly coreClientProvider: CoreClientProvider;

@inject(NotificationServiceServer)
protected readonly notificationService: NotificationServiceServer;

Expand Down Expand Up @@ -133,23 +130,4 @@ export class BoardDiscovery {
return availablePorts;
}

private async coreClient(): Promise<CoreClientProvider.Client> {
const coreClient = await new Promise<CoreClientProvider.Client>(async resolve => {
const client = await this.coreClientProvider.client();
if (client) {
resolve(client);
return;
}
const toDispose = this.coreClientProvider.onClientReady(async () => {
const client = await this.coreClientProvider.client();
if (client) {
toDispose.dispose();
resolve(client);
return;
}
});
});
return coreClient;
}

}
26 changes: 17 additions & 9 deletions arduino-ide-extension/src/node/core-client-provider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as grpc from '@grpc/grpc-js';
import { inject, injectable } from 'inversify';
import { Event, Emitter } from '@theia/core/lib/common/event';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { GrpcClientProvider } from './grpc-client-provider';
import { ArduinoCoreClient } from './cli-protocol/commands/commands_grpc_pb';
import * as commandsGrpcPb from './cli-protocol/commands/commands_grpc_pb';
Expand All @@ -27,7 +28,7 @@ export class CoreClientProvider extends GrpcClientProvider<CoreClientProvider.Cl
protected async reconcileClient(port: string | undefined): Promise<void> {
if (port && port === this._port) {
// No need to create a new gRPC client, but we have to update the indexes.
if (this._client) {
if (this._client && !(this._client instanceof Error)) {
await this.updateIndexes(this._client);
this.onClientReadyEmitter.fire();
}
Expand All @@ -48,7 +49,7 @@ export class CoreClientProvider extends GrpcClientProvider<CoreClientProvider.Cl
let resp: InitResp | undefined = undefined;
const stream = client.init(initReq);
stream.on('data', (data: InitResp) => resp = data);
stream.on('end', () => resolve(resp));
stream.on('end', () => resolve(resp!));
stream.on('error', err => reject(err));
});

Expand Down Expand Up @@ -175,20 +176,27 @@ export abstract class CoreClientAware {
protected readonly coreClientProvider: CoreClientProvider;

protected async coreClient(): Promise<CoreClientProvider.Client> {
const coreClient = await new Promise<CoreClientProvider.Client>(async resolve => {
const coreClient = await new Promise<CoreClientProvider.Client>(async (resolve, reject) => {
const handle = (c: CoreClientProvider.Client | Error) => {
if (c instanceof Error) {
reject(c);
} else {
resolve(c);
}
}
const client = await this.coreClientProvider.client();
if (client) {
resolve(client);
handle(client);
return;
}
const toDispose = this.coreClientProvider.onClientReady(async () => {
const toDispose = new DisposableCollection();
toDispose.push(this.coreClientProvider.onClientReady(async () => {
const client = await this.coreClientProvider.client();
if (client) {
toDispose.dispose();
resolve(client);
return;
handle(client);
}
});
toDispose.dispose();
}));
});
return coreClient;
}
Expand Down
11 changes: 6 additions & 5 deletions arduino-ide-extension/src/node/grpc-client-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export abstract class GrpcClientProvider<C> {
protected readonly configService: ConfigServiceImpl;

protected _port: string | number | undefined;
protected _client: C | undefined;
protected _client: C | Error | undefined;

@postConstruct()
protected init(): void {
Expand All @@ -28,20 +28,20 @@ export abstract class GrpcClientProvider<C> {
this.configService.onConfigChange(updateClient);
this.daemon.ready.then(updateClient);
this.daemon.onDaemonStopped(() => {
if (this._client) {
if (this._client && !(this._client instanceof Error)) {
this.close(this._client);
}
this._client = undefined;
this._port = undefined;
})
}

async client(): Promise<C | undefined> {
async client(): Promise<C | Error | undefined> {
try {
await this.daemon.ready;
return this._client;
} catch (error) {
return undefined;
return error;
}
}

Expand All @@ -50,7 +50,7 @@ export abstract class GrpcClientProvider<C> {
return; // Nothing to do.
}
this._port = port;
if (this._client) {
if (this._client && !(this._client instanceof Error)) {
this.close(this._client);
this._client = undefined;
}
Expand All @@ -60,6 +60,7 @@ export abstract class GrpcClientProvider<C> {
this._client = client;
} catch (error) {
this.logger.error('Could not create client for gRPC.', error)
this._client = error;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export class MonitorServiceImpl implements MonitorService {
if (!client) {
return Status.NOT_CONNECTED;
}
if (client instanceof Error) {
return { message: client.message };
}
const duplex = client.streamingOpen();
this.connection = { duplex, config };

Expand Down