Skip to content

Commit 0094775

Browse files
authored
log getWorkspaceAuthInfo error to GRPC (#82)
1 parent b90e3fe commit 0094775

File tree

4 files changed

+31
-12
lines changed

4 files changed

+31
-12
lines changed

src/common/utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ export function getServiceURL(gitpodHost: string): string {
116116

117117
export class WrapError extends Error {
118118
code: string | undefined;
119-
constructor(msg: string, err: any, code?: string) {
119+
constructor(
120+
msg: string,
121+
err: any,
122+
code?: string,
123+
readonly grpcCode?: number
124+
) {
120125
const isErr = err instanceof Error;
121126
super(isErr ? `${msg}: ${err.message}` : msg);
122127
if (isErr) {

src/local-ssh/ipc/extensionServiceServer.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { CreateSSHKeyPairRequest } from '@gitpod/supervisor-api-grpcweb/lib/cont
2525
import * as ssh2 from 'ssh2';
2626
import { ParsedKey } from 'ssh2-streams';
2727
import { isPortUsed } from '../../common/ports';
28+
import { WrapError } from '../../common/utils';
2829

2930
const phaseMap: Record<WorkspaceInstanceStatus_Phase, WorkspaceInstancePhase | undefined> = {
3031
[WorkspaceInstanceStatus_Phase.CREATING]: 'pending',
@@ -74,6 +75,8 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
7475
}
7576

7677
async getWorkspaceAuthInfo(request: GetWorkspaceAuthInfoRequest, _context: CallContext): Promise<GetWorkspaceAuthInfoResponse> {
78+
let userId: string | undefined;
79+
let instanceId: string | undefined;
7780
try {
7881
if (new URL(this.hostService.gitpodHost).host !== new URL(request.gitpodHost).host) {
7982
this.logService.error(`gitpod host mismatch, actual: ${this.hostService.gitpodHost} target: ${request.gitpodHost}`);
@@ -83,7 +86,7 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
8386
if (!accessToken) {
8487
throw new ServerError(Status.INTERNAL, 'no access token found');
8588
}
86-
const userId = this.sessionService.getUserId();
89+
userId = this.sessionService.getUserId();
8790
const workspaceId = request.workspaceId;
8891
// TODO(lssh): Get auth info according to `request.gitpodHost`
8992
const gitpodHost = this.hostService.gitpodHost;
@@ -101,7 +104,7 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
101104
}
102105
const url = new URL(ideUrl);
103106
const workspaceHost = url.host.substring(url.host.indexOf('.') + 1);
104-
const instanceId = (usePublicApi ? (workspace as Workspace).status?.instance?.instanceId : (workspace as WorkspaceInfo).latestInstance?.id) as string;
107+
instanceId = (usePublicApi ? (workspace as Workspace).status?.instance?.instanceId : (workspace as WorkspaceInfo).latestInstance?.id) as string;
105108

106109
const sshkey = phase === 'running' ? (await this.getWorkspaceSSHKey(ownerToken, workspaceId, workspaceHost)) : '';
107110

@@ -116,11 +119,20 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
116119
phase: phase ?? 'unknown',
117120
};
118121
} catch (e) {
119-
this.logService.error(e, 'failed to get workspace auth info');
120-
if (e instanceof ServerError) {
121-
throw e;
122+
let code = Status.INTERNAL;
123+
if (e instanceof WrapError && typeof e.grpcCode === 'number') {
124+
code = e.grpcCode
122125
}
123-
throw new ServerError(Status.UNAVAILABLE, e.toString());
126+
const wrapErr = new WrapError('failed to get workspace auth info', e);
127+
this.logService.error(wrapErr);
128+
this.telemetryService.sendTelemetryException(wrapErr, {
129+
gitpodHost: request.gitpodHost,
130+
workspaceId: request.workspaceId,
131+
instanceId,
132+
userId,
133+
});
134+
135+
throw new ServerError(code, wrapErr.toString());
124136
}
125137
}
126138

src/local-ssh/proxy.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ function getClientOptions(): ClientOptions {
4545
type FailedToProxyCode = 'SSH.AuthenticationFailed' | 'TUNNEL.AuthenticateSSHKeyFailed' | 'NoRunningInstance' | 'FailedToGetAuthInfo' | 'GitpodHostMismatch' | 'NoAccessTokenFound';
4646

4747
// IgnoredFailedCodes contains the failreCode that don't need to send error report
48-
const IgnoredFailedCodes: FailedToProxyCode[] = ['NoRunningInstance'];
48+
const IgnoredFailedCodes: (FailedToProxyCode | string)[] = ['NoRunningInstance'];
4949

5050
class FailedToProxyError extends Error {
51-
constructor(public readonly failureCode: FailedToProxyCode, originError?: Error) {
51+
constructor(public readonly failureCode: FailedToProxyCode | string, originError?: Error) {
5252
const msg = 'Failed to proxy connection: ' + failureCode;
5353
super(originError ? (msg + ': ' + originError.toString()) : msg);
5454
this.name = 'FailedToProxyError';
@@ -68,7 +68,7 @@ interface SSHUserFlowTelemetry extends UserFlowTelemetryProperties {
6868
workspaceId: string;
6969
instanceId?: string;
7070
userId?: string;
71-
failureCode?: FailedToProxyCode;
71+
failureCode?: FailedToProxyCode | string;
7272
}
7373

7474
class WebSocketSSHProxy {
@@ -243,14 +243,16 @@ class WebSocketSSHProxy {
243243
async retryGetWorkspaceInfo(username: string) {
244244
return retry(async () => {
245245
return this.extensionIpc.getWorkspaceAuthInfo({ workspaceId: username, gitpodHost: this.options.host }).catch(e => {
246+
let failureCode = 'FailedToGetAuthInfo';
246247
if (e instanceof ClientError) {
247248
if (e.code === Status.FAILED_PRECONDITION && e.message.includes('gitpod host mismatch')) {
248249
throw new FailedToProxyError('GitpodHostMismatch', e);
249250
} else if (e.code === Status.INTERNAL && e.message.includes('no access token found')) {
250251
throw new FailedToProxyError('NoAccessTokenFound', e);
251252
}
253+
failureCode += ':' + Status[e.code];
252254
}
253-
throw new FailedToProxyError('FailedToGetAuthInfo', e);
255+
throw new FailedToProxyError(failureCode, e);
254256
});
255257
}, 200, 50);
256258
}

src/publicApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export class GitpodPublicApi extends Disposable implements IGitpodAPI {
215215
// https://github.com/gitpod-io/gitpod/blob/d41a38ba83939856e5292e30912f52e749787db1/components/public-api-server/pkg/auth/middleware.go#L73
216216
// https://github.com/gitpod-io/gitpod/blob/d41a38ba83939856e5292e30912f52e749787db1/components/public-api-server/pkg/proxy/errors.go#L30
217217
// NOTE: WrapError will omit error's other properties
218-
throw new WrapError('Failed to call public API', err, 'PublicAPI:' + Code[err.code]);
218+
throw new WrapError('Failed to call public API', err, 'PublicAPI:' + Code[err.code], err.code);
219219
}
220220
}
221221

0 commit comments

Comments
 (0)