Skip to content

Commit 3649e17

Browse files
authored
Process errors from supervisor grpc-web lib (#84)
* Process errors from supervisor grpc-web lib * 💄 * Make break easier * 💄 * 1
1 parent 1b92e4a commit 3649e17

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

src/local-ssh/ipc/extensionServiceServer.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ import { ExperimentalSettings } from '../../experiments';
1818
import { Configuration } from '../../configuration';
1919
import { timeout } from '../../common/async';
2020
import { BrowserHeaders } from 'browser-headers';
21-
import { ControlServiceClient } from '@gitpod/supervisor-api-grpcweb/lib/control_pb_service';
21+
import { ControlServiceClient, ServiceError } from '@gitpod/supervisor-api-grpcweb/lib/control_pb_service';
2222
import { NodeHttpTransport } from '@improbable-eng/grpc-web-node-http-transport';
2323
import { CreateSSHKeyPairRequest } from '@gitpod/supervisor-api-grpcweb/lib/control_pb';
2424
import * as ssh2 from 'ssh2';
2525
import { ParsedKey } from 'ssh2-streams';
2626
import { isPortUsed } from '../../common/ports';
2727
import { WrapError } from '../../common/utils';
28-
import { ConnectError } from '@bufbuild/connect';
28+
import { ConnectError, Code } from '@bufbuild/connect';
29+
30+
function isServiceError(obj: any): obj is ServiceError {
31+
// eslint-disable-next-line eqeqeq
32+
return obj != null && typeof obj === 'object' && typeof obj.metadata != null && typeof obj.code === 'number' && typeof obj.message === 'string';
33+
}
2934

3035
const phaseMap: Record<WorkspaceInstanceStatus_Phase, WorkspaceInstancePhase | undefined> = {
3136
[WorkspaceInstanceStatus_Phase.CREATING]: 'pending',
@@ -60,7 +65,9 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
6065
const privateKey = await new Promise<string>((resolve, reject) => {
6166
client.createSSHKeyPair(new CreateSSHKeyPairRequest(), metadata, (err, resp) => {
6267
if (err) {
63-
return reject(err);
68+
// codes of grpc-web are align with grpc and connect
69+
// see https://github.com/improbable-eng/grpc-web/blob/1d9bbb09a0990bdaff0e37499570dbc7d6e58ce8/client/grpc-web/src/Code.ts#L1
70+
return reject(new WrapError('Failed to call supervisor API', err, 'SupervisorAPI:' + Code[err.code]));
6471
}
6572
resolve(resp!.toObject().privateKey);
6673
});
@@ -124,8 +131,8 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
124131
};
125132
} catch (e) {
126133
let code = Status.INTERNAL;
127-
if (e instanceof WrapError && e.cause instanceof ConnectError) {
128-
code = e.cause.code as unknown as Status;
134+
if (e instanceof WrapError && (e.cause instanceof ConnectError || isServiceError(e.cause))) {
135+
code = e.cause.code;
129136
}
130137
const wrapErr = new WrapError('failed to get workspace auth info', e);
131138
this.logService.error(wrapErr);
@@ -134,6 +141,7 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
134141
workspaceId: request.workspaceId,
135142
instanceId,
136143
userId,
144+
wrapCode: wrapErr.code,
137145
});
138146

139147
throw new ServerError(code, wrapErr.toString());

src/local-ssh/proxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class WebSocketSSHProxy {
152152

153153
this.sendUserStatusFlow('failed');
154154
if (sendErrorReport) {
155-
this.sendErrorReport(this.flow, err, 'failed to authenticate proxy with username: ' + e.username ?? '');
155+
this.sendErrorReport(this.flow, err, 'failed to authenticate proxy');
156156
}
157157

158158
// Await a few seconds to delay showing ssh extension error modal dialog

0 commit comments

Comments
 (0)