From ae38d864766a34dbea833dc7cda773a6abca7a30 Mon Sep 17 00:00:00 2001 From: Sven Efftinge Date: Mon, 23 Oct 2023 11:20:31 +0200 Subject: [PATCH] [linting] Enable eslint/no-unsafe-argument (#18965) --- components/gitpod-db/.eslintrc | 3 + .../gitpod-db/src/migrate-migrations.ts | 3 +- components/gitpod-db/src/periodic-deleter.ts | 17 +- .../gitpod-db/src/redis/publisher.spec.ts | 4 +- components/gitpod-db/src/tables.spec.ts | 6 +- components/gitpod-db/src/test/reset-db.ts | 2 +- components/gitpod-db/src/traced-db.ts | 1 + .../gitpod-db/src/typeorm/team-db-impl.ts | 2 +- .../gitpod-db/src/typeorm/transformer.ts | 3 + .../gitpod-db/src/typeorm/user-db-impl.ts | 3 +- .../src/typeorm/workspace-db-impl.ts | 40 ++--- components/gitpod-db/src/wait-for-db.ts | 4 +- .../gitpod-db/src/workspace-db.spec.db.ts | 36 ++++- components/gitpod-protocol/.eslintrc | 3 + .../gitpod-protocol/src/gitpod-file-parser.ts | 3 +- .../gitpod-protocol/src/messaging/error.ts | 4 +- .../src/messaging/proxy-factory.ts | 20 ++- .../src/public-api-converter.spec.ts | 1 + .../src/util/async-iterator.ts | 1 + .../gitpod-protocol/src/util/deferred.ts | 4 +- .../src/util/gitpod-host-url.ts | 2 + .../gitpod-protocol/src/util/logging.ts | 148 ++++++++++-------- .../gitpod-protocol/src/util/queue.spec.ts | 2 + .../gitpod-protocol/src/util/scrubbing.ts | 4 +- .../gitpod-protocol/src/util/tracing.ts | 6 +- .../gitpod-protocol/src/workspace-cluster.ts | 1 + components/server/.eslintrc | 1 + components/server/src/analytics.ts | 2 +- components/server/src/api/server.ts | 3 +- .../server/src/auth/bearer-authenticator.ts | 2 +- .../server/src/auth/generic-auth-provider.ts | 3 +- .../bitbucket-server-api.spec.ts | 1 + .../bitbucket-server-context-parser.spec.ts | 1 + .../bitbucket-server-file-provider.spec.ts | 2 + ...tbucket-server-repository-provider.spec.ts | 1 + .../src/bitbucket/bitbucket-auth-provider.ts | 1 + components/server/src/github/api.ts | 4 +- .../server/src/github/github-app-support.ts | 1 + .../server/src/github/github-auth-provider.ts | 1 + .../src/github/github-context-parser.ts | 1 + .../server/src/gitlab/gitlab-auth-provider.ts | 4 +- .../server/src/iam/iam-session-app.spec.ts | 1 + components/server/src/init.ts | 4 +- components/server/src/linkedin-service.ts | 14 +- .../server/src/messaging/redis-subscriber.ts | 11 +- components/server/src/monitoring-endpoints.ts | 1 + .../server/src/orgs/organization-service.ts | 3 +- .../server/src/prebuilds/bitbucket-app.ts | 1 + .../src/prebuilds/bitbucket-server-app.ts | 1 + .../bitbucket-server-service.spec.ts | 1 + components/server/src/prebuilds/github-app.ts | 4 +- .../src/prebuilds/github-enterprise-app.ts | 1 + .../src/prebuilds/prebuild-manager.spec.ts | 1 + components/server/src/server.ts | 6 +- .../test/service-testing-container-module.ts | 2 +- components/server/src/user/user-controller.ts | 1 + .../server/src/user/user-deletion-service.ts | 3 +- components/server/src/user/user-service.ts | 6 +- .../websocket/websocket-connection-manager.ts | 3 +- .../src/workspace/config-provider.spec.ts | 1 + .../server/src/workspace/config-provider.ts | 2 +- .../envvar-prefix-context-parser.spec.ts | 1 + .../src/workspace/gitpod-server-impl.ts | 65 +++----- .../server/src/workspace/workspace-service.ts | 3 +- .../server/src/workspace/workspace-starter.ts | 6 +- 65 files changed, 281 insertions(+), 212 deletions(-) diff --git a/components/gitpod-db/.eslintrc b/components/gitpod-db/.eslintrc index e4a604c01ff860..00a6d9b51df5f2 100644 --- a/components/gitpod-db/.eslintrc +++ b/components/gitpod-db/.eslintrc @@ -10,6 +10,7 @@ }, "rules": { "no-var": "error", + "no-void": "error", "prefer-const": "error", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/ban-types": "off", @@ -17,6 +18,7 @@ "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-non-null-asserted-optional-chain": "off", "@typescript-eslint/no-inferrable-types": "off", "@typescript-eslint/no-misused-promises": [ @@ -28,6 +30,7 @@ "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unused-vars": [ "error", { diff --git a/components/gitpod-db/src/migrate-migrations.ts b/components/gitpod-db/src/migrate-migrations.ts index 2e49c69d81328e..9cfbd7c6232a44 100644 --- a/components/gitpod-db/src/migrate-migrations.ts +++ b/components/gitpod-db/src/migrate-migrations.ts @@ -7,6 +7,7 @@ import { TypeORM } from "./typeorm/typeorm"; import { Config } from "./config"; import { MigrateMigrations0_2_0 } from "./typeorm/migrate-migrations-0_2_0"; +import { log } from "@gitpod/gitpod-protocol/lib/util/logging"; async function migrateMigrationsTable() { const config = new Config(); @@ -17,7 +18,7 @@ async function migrateMigrationsTable() { const migration_0_2_0 = new MigrateMigrations0_2_0(); await migration_0_2_0.up(runner); - conn.close(); + conn.close().catch((err) => log.error("cannot close connection", err)); console.log("successfully migrated 'migrations' table."); } diff --git a/components/gitpod-db/src/periodic-deleter.ts b/components/gitpod-db/src/periodic-deleter.ts index 9175020c6233bd..68444453b6e3f1 100644 --- a/components/gitpod-db/src/periodic-deleter.ts +++ b/components/gitpod-db/src/periodic-deleter.ts @@ -39,18 +39,13 @@ export class PeriodicDbDeleter { const pendingDeletions: Promise[] = []; for (const { deletions } of toBeDeleted.reverse()) { for (const deletion of deletions) { - pendingDeletions.push( - this.query(deletion).catch((err) => - log.error( - `[PeriodicDbDeleter] sync error`, - { - periodicDeleterTickId: tickID, - query: deletion, - }, - err, - ), - ), + const promise: Promise = this.query(deletion).catch((err) => + log.error(`[PeriodicDbDeleter] sync error`, err, { + periodicDeleterTickId: tickID, + query: deletion, + }), ); + pendingDeletions.push(promise); } } await Promise.all(pendingDeletions); diff --git a/components/gitpod-db/src/redis/publisher.spec.ts b/components/gitpod-db/src/redis/publisher.spec.ts index 8b15dd7926ce8f..c05c8a6dc6073e 100644 --- a/components/gitpod-db/src/redis/publisher.spec.ts +++ b/components/gitpod-db/src/redis/publisher.spec.ts @@ -31,8 +31,8 @@ class TestRedisPublisher { @test public publishInstanceUpdate() { const publisher = this.container.get(RedisPublisher); - expect(() => { - publisher.publishInstanceUpdate({ + expect(async () => { + await publisher.publishInstanceUpdate({ ownerID: "123-owner", instanceID: "123", workspaceID: "foo-bar-123", diff --git a/components/gitpod-db/src/tables.spec.ts b/components/gitpod-db/src/tables.spec.ts index 55168ffb91c174..8fd1556958c231 100644 --- a/components/gitpod-db/src/tables.spec.ts +++ b/components/gitpod-db/src/tables.spec.ts @@ -19,11 +19,7 @@ class TablesSpec { @test(timeout(10000)) public async createAndFindATeam() { const thing = new GitpodTableDescriptionProvider(); - try { - thing.getSortedTables(); - } catch (error) { - expect.fail(error); - } + expect(() => thing.getSortedTables()).to.not.throw(); } } diff --git a/components/gitpod-db/src/test/reset-db.ts b/components/gitpod-db/src/test/reset-db.ts index 8e5445c2819903..b4a0b05218a514 100644 --- a/components/gitpod-db/src/test/reset-db.ts +++ b/components/gitpod-db/src/test/reset-db.ts @@ -12,7 +12,7 @@ export async function resetDB(typeorm: TypeORM) { const conn = await typeorm.getConnection(); const users = await conn.getRepository(DBUser).find(); // delete all users except the builtin users - conn.getRepository(DBUser).remove(users.filter((u) => !isBuiltinUser(u.id))); + await conn.getRepository(DBUser).remove(users.filter((u) => !isBuiltinUser(u.id))); const deletions = conn.entityMetadatas .filter((meta) => meta.tableName !== "d_b_user") diff --git a/components/gitpod-db/src/traced-db.ts b/components/gitpod-db/src/traced-db.ts index 867c8b79b4e78e..1898f0cc266905 100644 --- a/components/gitpod-db/src/traced-db.ts +++ b/components/gitpod-db/src/traced-db.ts @@ -17,6 +17,7 @@ export class DBWithTracing { public trace(ctx: TraceContext): T { return new Proxy(this.db, { get: (_target: any, name: string) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const f = Reflect.get(_target, name); if (!f) { return undefined; diff --git a/components/gitpod-db/src/typeorm/team-db-impl.ts b/components/gitpod-db/src/typeorm/team-db-impl.ts index 0268a784a80428..f2a66c1ddd2531 100644 --- a/components/gitpod-db/src/typeorm/team-db-impl.ts +++ b/components/gitpod-db/src/typeorm/team-db-impl.ts @@ -254,7 +254,7 @@ export class TeamDBImpl extends TransactionalDBImpl implements TeamDB { const orgSettings = await orgSettingsRepo.findOne({ where: { orgId } }); if (orgSettings) { orgSettings.deleted = true; - orgSettingsRepo.save(orgSettings); + await orgSettingsRepo.save(orgSettings); } } diff --git a/components/gitpod-db/src/typeorm/transformer.ts b/components/gitpod-db/src/typeorm/transformer.ts index 017eeb783b1569..944e9f72d4fb3b 100644 --- a/components/gitpod-db/src/typeorm/transformer.ts +++ b/components/gitpod-db/src/typeorm/transformer.ts @@ -64,6 +64,7 @@ export namespace Transformer { }, from(value: any): any { // From TIMESTAMP to ISO string + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return new Date(Date.parse(value)).toISOString(); }, }; @@ -74,6 +75,7 @@ export namespace Transformer { return JSON.stringify(value || defaultValue); }, from(value: any): any { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return JSON.parse(value); }, }; @@ -85,6 +87,7 @@ export namespace Transformer { return encryptionServiceProvider().encrypt(value); }, from(value: any): any { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return encryptionServiceProvider().decrypt(value); }, }; diff --git a/components/gitpod-db/src/typeorm/user-db-impl.ts b/components/gitpod-db/src/typeorm/user-db-impl.ts index d1f76e043defc2..cb9c3e9b9ad4d8 100644 --- a/components/gitpod-db/src/typeorm/user-db-impl.ts +++ b/components/gitpod-db/src/typeorm/user-db-impl.ts @@ -379,6 +379,7 @@ export class TypeORMUserDBImpl extends TransactionalDBImpl implements Us } const res = await userRepo.query(query); const count = res[0].cnt; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return Number.parseInt(count); } @@ -598,7 +599,7 @@ export class TypeORMUserDBImpl extends TransactionalDBImpl implements Us } async revoke(accessTokenToken: OAuthToken): Promise { const tokenHash = crypto.createHash("sha256").update(accessTokenToken.accessToken, "utf8").digest("hex"); - this.deleteGitpodToken(tokenHash); + await this.deleteGitpodToken(tokenHash); } async isRefreshTokenRevoked(refreshToken: OAuthToken): Promise { return Date.now() > (refreshToken.refreshTokenExpiresAt?.getTime() ?? 0); diff --git a/components/gitpod-db/src/typeorm/workspace-db-impl.ts b/components/gitpod-db/src/typeorm/workspace-db-impl.ts index 7c4ced087ac406..b3480dc1d2081b 100644 --- a/components/gitpod-db/src/typeorm/workspace-db-impl.ts +++ b/components/gitpod-db/src/typeorm/workspace-db-impl.ts @@ -6,6 +6,7 @@ import { AdminGetWorkspacesQuery, + CommitContext, PrebuildInfo, PrebuiltWorkspace, PrebuiltWorkspaceState, @@ -143,9 +144,10 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp // `cloneUrl` is stored redundandly to optimize for `getWorkspaceCountByCloneURL`. // As clone URLs are lesser constrained we want to shorten the value to work well with the indexed column. - const cloneUrl: string = this.toCloneUrl255((workspace as any).context?.repository?.cloneUrl || ""); - - dbWorkspace.cloneUrl = cloneUrl; + if (CommitContext.is(dbWorkspace.context)) { + const cloneUrl = this.toCloneUrl255(dbWorkspace.context.repository.cloneUrl); + dbWorkspace.cloneUrl = cloneUrl; + } return await workspaceRepo.save(dbWorkspace); } @@ -167,17 +169,12 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp } public async findByInstanceId(instanceId: string): Promise { - const workspaceRepo = await this.getWorkspaceRepo(); - const maybeRawWorkspaces = (await workspaceRepo.query( - `SELECT ws.* FROM d_b_workspace as ws - LEFT OUTER JOIN d_b_workspace_instance as wsi ON wsi.workspaceId = ws.id - WHERE wsi.id = ?;`, - [instanceId], - )) as object[]; - if (!maybeRawWorkspaces || maybeRawWorkspaces.length !== 1) { + const instanceRepo = await this.getWorkspaceInstanceRepo(); + const instance = await instanceRepo.findOne(instanceId); + if (!instance) { return undefined; } - return this.makeWorkspace(maybeRawWorkspaces[0]); + return this.findById(instance.workspaceId); } public async find(options: FindWorkspacesOptions): Promise { @@ -265,16 +262,6 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp }); } - private makeWorkspace(raw: any): DBWorkspace | undefined { - if (!raw) return undefined; - return { - ...raw, - config: JSON.parse(raw.config), - context: JSON.parse(raw.context), - pinned: (raw.pinned && JSON.parse(raw.pinned)) || undefined, - }; - } - public async updateLastHeartbeat( instanceId: string, userId: string, @@ -285,7 +272,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp "INSERT INTO d_b_workspace_instance_user(instanceId, userId, lastSeen) VALUES (?, ?, timestamp ?) ON DUPLICATE KEY UPDATE lastSeen = timestamp ?, wasClosed = ?"; const lastSeen = this.toTimestampString(newHeartbeat); const workspaceInstanceUserRepo = await this.getWorkspaceInstanceUserRepo(); - workspaceInstanceUserRepo.query(query, [instanceId, userId, lastSeen, lastSeen, wasClosed || false]); + await workspaceInstanceUserRepo.query(query, [instanceId, userId, lastSeen, lastSeen, wasClosed || false]); } private toTimestampString(date: Date) { @@ -302,6 +289,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp if (result && result.length > 0 && result[0].lastSeen) { return { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument lastSeen: new Date(result[0].lastSeen), wasClosed: Boolean(result[0].wasClosed), }; @@ -401,7 +389,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp userId?: string, includeStopping: boolean = false, ): Promise { - const params: any = {}; + const params: { region?: string } = {}; const conditions = ["wsi.phasePersisted != 'stopped'", "wsi.deleted != TRUE"]; if (!includeStopping) { // This excludes instances in a 'stopping' phase @@ -411,7 +399,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp params.region = workspaceClusterName; conditions.push("wsi.region = :region"); } - const joinParams: any = {}; + const joinParams: { userId?: string } = {}; const joinConditions = []; if (userId) { joinParams.userId = userId; @@ -501,6 +489,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp resultSessions.push({ workspace: { id: session.ws_id, + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument context: JSON.parse(session.ws_context), contextURL: session.ws_contextURL, type: session.ws_type, @@ -980,6 +969,7 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl imp : "wsi.id = (SELECT i.id FROM d_b_workspace_instance AS i WHERE i.workspaceId = ws.id ORDER BY i.creationTime DESC LIMIT 1)" }`, ) + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument .where(whereConditions.join(" AND "), whereConditionParams) .orderBy(orderField, orderDir) .take(limit) diff --git a/components/gitpod-db/src/wait-for-db.ts b/components/gitpod-db/src/wait-for-db.ts index df1114cd04f044..166d7796171ef5 100644 --- a/components/gitpod-db/src/wait-for-db.ts +++ b/components/gitpod-db/src/wait-for-db.ts @@ -35,9 +35,9 @@ function connectOrReschedule(attempt: number) { } } -function rescheduleConnectionAttempt(attempt: number, err: Error) { +function rescheduleConnectionAttempt(attempt: number, err: unknown) { if (attempt == totalAttempts) { - console.log(`Could not connect within ${totalAttempts} attempts. Stopping.`); + console.log(`Could not connect within ${totalAttempts} attempts. Stopping.`, err); process.exit(1); } console.log(`Connection attempt ${attempt}/${totalAttempts} failed. Retrying in ${retryPeriod / 1000} seconds.`); diff --git a/components/gitpod-db/src/workspace-db.spec.db.ts b/components/gitpod-db/src/workspace-db.spec.db.ts index 3c966b07d2c7f9..1caf61a814e6f0 100644 --- a/components/gitpod-db/src/workspace-db.spec.db.ts +++ b/components/gitpod-db/src/workspace-db.spec.db.ts @@ -41,7 +41,13 @@ class WorkspaceDBSpec { tasks: [], }, projectId: this.projectAID, - context: { title: "example" }, + context: { + title: "example", + repository: { + cloneUrl: "https://github.com/gitpod-io/gitpod", + }, + revision: "abc", + }, contextURL: "example.org", description: "blabla", ownerId: this.userId, @@ -105,7 +111,13 @@ class WorkspaceDBSpec { tasks: [], }, projectId: this.projectBID, - context: { title: "example" }, + context: { + title: "example", + repository: { + cloneUrl: "https://github.com/gitpod-io/gitpod", + }, + revision: "abc", + }, contextURL: "https://github.com/gitpod-io/gitpod", description: "Gitpod", ownerId: this.userId, @@ -145,7 +157,13 @@ class WorkspaceDBSpec { image: "", tasks: [], }, - context: { title: "example" }, + context: { + title: "example", + repository: { + cloneUrl: "https://github.com/gitpod-io/gitpod", + }, + revision: "abc", + }, contextURL: "example.org", description: "blabla", ownerId: this.userId, @@ -206,6 +224,16 @@ class WorkspaceDBSpec { fail("Rollback failed"); } + @test(timeout(10000)) + public async testFindByInstanceId() { + await this.db.transaction(async (db) => { + await Promise.all([db.store(this.ws), db.storeInstance(this.wsi1)]); + const dbResult = await db.findByInstanceId(this.wsi1.id); + const expected = await db.findById(this.wsi1.workspaceId); + expect(dbResult).to.deep.eq(expected); + }); + } + @test(timeout(10000)) public async testFindPrebuildsForGC_oldPrebuildNoUsage() { await this.createPrebuild(2); @@ -583,6 +611,7 @@ class WorkspaceDBSpec { repository: { cloneUrl: inactiveRepo, }, + revision: "abc", }, config: {}, type: "regular", @@ -599,6 +628,7 @@ class WorkspaceDBSpec { repository: { cloneUrl: activeRepo, }, + revision: "abc", }, config: {}, type: "regular", diff --git a/components/gitpod-protocol/.eslintrc b/components/gitpod-protocol/.eslintrc index e4a604c01ff860..00a6d9b51df5f2 100644 --- a/components/gitpod-protocol/.eslintrc +++ b/components/gitpod-protocol/.eslintrc @@ -10,6 +10,7 @@ }, "rules": { "no-var": "error", + "no-void": "error", "prefer-const": "error", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/ban-types": "off", @@ -17,6 +18,7 @@ "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-non-null-asserted-optional-chain": "off", "@typescript-eslint/no-inferrable-types": "off", "@typescript-eslint/no-misused-promises": [ @@ -28,6 +30,7 @@ "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unused-vars": [ "error", { diff --git a/components/gitpod-protocol/src/gitpod-file-parser.ts b/components/gitpod-protocol/src/gitpod-file-parser.ts index d742318a815c01..06b8a3f2eb1184 100644 --- a/components/gitpod-protocol/src/gitpod-file-parser.ts +++ b/components/gitpod-protocol/src/gitpod-file-parser.ts @@ -13,7 +13,7 @@ import { WorkspaceConfig, PortRangeConfig } from "./protocol"; export type MaybeConfig = WorkspaceConfig | undefined; const schema = require("../data/gitpod-schema.json"); -const validate = new Ajv().compile(schema); +const validate = new Ajv().compile(schema as object); const defaultParseOptions = { acceptPortRanges: false, }; @@ -33,6 +33,7 @@ export class GitpodFileParser { }; try { const parsedConfig = yaml.safeLoad(content) as any; + // eslint-disable-next-line @typescript-eslint/no-floating-promises validate(parsedConfig); const validationErrors = validate.errors ? validate.errors.map((e) => e.message || e.keyword) : undefined; if (validationErrors && validationErrors.length > 0) { diff --git a/components/gitpod-protocol/src/messaging/error.ts b/components/gitpod-protocol/src/messaging/error.ts index 655edc73197949..64e8946fc573df 100644 --- a/components/gitpod-protocol/src/messaging/error.ts +++ b/components/gitpod-protocol/src/messaging/error.ts @@ -38,9 +38,11 @@ export namespace ApplicationError { } } - export function fromGRPCError(e: any & Error, data?: any): ApplicationError { + export function fromGRPCError(e: any, data?: any): ApplicationError { // Argument e should be ServerErrorResponse // But to reduce dependency requirement, we use Error here + + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return new ApplicationError(categorizeRPCError(e.code), e.message, data); } diff --git a/components/gitpod-protocol/src/messaging/proxy-factory.ts b/components/gitpod-protocol/src/messaging/proxy-factory.ts index 73626fe3353ade..39539810949819 100644 --- a/components/gitpod-protocol/src/messaging/proxy-factory.ts +++ b/components/gitpod-protocol/src/messaging/proxy-factory.ts @@ -99,10 +99,14 @@ export class JsonRpcProxyFactory implements ProxyHandler { protected waitForConnection(): void { this.connectionPromise = new Promise((resolve) => (this.connectionPromiseResolve = resolve)); - this.connectionPromise.then((connection) => { - connection.onClose(() => this.fireConnectionClosed()); - this.fireConnectionOpened(); - }); + this.connectionPromise + .then((connection) => { + connection.onClose(() => this.fireConnectionClosed()); + this.fireConnectionOpened(); + }) + .catch((err) => { + log.error("Error while waiting for connection", err); + }); } fireConnectionClosed() { @@ -120,7 +124,9 @@ export class JsonRpcProxyFactory implements ProxyHandler { * response. */ listen(connection: MessageConnection) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument connection.onRequest((method: string, ...params: any[]) => this.onRequest(method, ...params)); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument connection.onNotification((method: string, ...params: any[]) => this.onNotification(method, ...params)); connection.onDispose(() => this.waitForConnection()); connection.listen(); @@ -172,7 +178,7 @@ export class JsonRpcProxyFactory implements ProxyHandler { * If `T` implements `JsonRpcServer` then a client is used as a target object for a remote target object. */ createProxy(): JsonRpcProxy { - const result = new Proxy(this as any, this); + const result = new Proxy(this as unknown as T, this); return result as any; } @@ -217,11 +223,13 @@ export class JsonRpcProxyFactory implements ProxyHandler { new Promise((resolve, reject) => { try { if (isNotify) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument connection.sendNotification(p.toString(), ...args); resolve(undefined); } else { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const resultPromise = connection.sendRequest(p.toString(), ...args) as Promise; - resultPromise.catch((err: any) => reject(err)).then((result: any) => resolve(result)); + resultPromise.then(resolve, reject); } } catch (err) { reject(err); diff --git a/components/gitpod-protocol/src/public-api-converter.spec.ts b/components/gitpod-protocol/src/public-api-converter.spec.ts index bf8760e3d4e411..a1a856613255f9 100644 --- a/components/gitpod-protocol/src/public-api-converter.spec.ts +++ b/components/gitpod-protocol/src/public-api-converter.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2023 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/gitpod-protocol/src/util/async-iterator.ts b/components/gitpod-protocol/src/util/async-iterator.ts index c231ddc8c5c198..fbf9402121fc83 100644 --- a/components/gitpod-protocol/src/util/async-iterator.ts +++ b/components/gitpod-protocol/src/util/async-iterator.ts @@ -51,6 +51,7 @@ export class AsyncCachingIteratorImpl implements AsyncIterableIterator, As } this.cacheRead = true; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const result = await this.iterable.next(value); if (!result.done) { this.cache.push(result.value); diff --git a/components/gitpod-protocol/src/util/deferred.ts b/components/gitpod-protocol/src/util/deferred.ts index 800752fcca56cd..5a961aaae7dcd0 100644 --- a/components/gitpod-protocol/src/util/deferred.ts +++ b/components/gitpod-protocol/src/util/deferred.ts @@ -17,9 +17,9 @@ export class Deferred { } promise = new Promise((resolve, reject) => { - this.resolve = (o) => { + this.resolve = (o?: T) => { this.isResolved = true; - resolve(o as any); + resolve(o as T); clearTimeout(this.timer); }; this.reject = (e) => { diff --git a/components/gitpod-protocol/src/util/gitpod-host-url.ts b/components/gitpod-protocol/src/util/gitpod-host-url.ts index 84b0bed03e217a..74915fdacca7b2 100644 --- a/components/gitpod-protocol/src/util/gitpod-host-url.ts +++ b/components/gitpod-protocol/src/util/gitpod-host-url.ts @@ -25,6 +25,7 @@ export class GitpodHostUrl { readonly url: URL; constructor(url: string) { + //HACK - we don't want clients to pass in a URL object, but we need to use it internally const urlParam = url as any; if (typeof urlParam === "string") { // public constructor @@ -68,6 +69,7 @@ export class GitpodHostUrl { update.pathname = "/" + update.pathname; } const result = Object.assign(new URL(this.toString()), update); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return new GitpodHostUrl(result); } diff --git a/components/gitpod-protocol/src/util/logging.ts b/components/gitpod-protocol/src/util/logging.ts index 17753aac67a2de..4542b703782d71 100644 --- a/components/gitpod-protocol/src/util/logging.ts +++ b/components/gitpod-protocol/src/util/logging.ts @@ -6,7 +6,7 @@ import { scrubber } from "./scrubbing"; -const inspect: (object: any) => string = require("util").inspect; // undefined in frontend +const inspect: (object: unknown) => string = require("util").inspect; // undefined in frontend const plainLogging: boolean = false; // set to true during development to get non JSON output let jsonLogging: boolean = false; @@ -31,6 +31,10 @@ export namespace LogContext { export function setAugmenter(augmenter: Augmenter): void { logContextAugmenter = augmenter; } + + /** + * @deprecated create LogContext directly + */ export function from(params: { userId?: string; user?: any; request?: any }) { return { sessionId: params.request?.requestID, @@ -44,67 +48,67 @@ export interface LogPayload { } export namespace log { - export function error(context: LogContext, message: string, error: any, payload: LogPayload): void; - export function error(context: LogContext, message: string, error: any): void; + export function error(context: LogContext, message: string, error: unknown, payload: LogPayload): void; + export function error(context: LogContext, message: string, error: unknown): void; export function error(context: LogContext, message: string, payload: LogPayload): void; export function error(context: LogContext, message: string): void; - export function error(context: LogContext, error: any, payload: LogPayload): void; - export function error(context: LogContext, error: any): void; - export function error(message: string, error: any, payload: LogPayload): void; - export function error(message: string, error: any): void; + export function error(context: LogContext, error: unknown, payload: LogPayload): void; + export function error(context: LogContext, error: unknown): void; + export function error(message: string, error: unknown, payload: LogPayload): void; + export function error(message: string, error: unknown): void; export function error(message: string, payload: LogPayload): void; export function error(message: string): void; - export function error(error: any, payload: LogPayload): void; - export function error(error: any): void; - export function error(...args: any[]): void { + export function error(error: unknown, payload: LogPayload): void; + export function error(error: unknown): void; + export function error(...args: unknown[]): void { errorLog(false, args); } - export function warn(context: LogContext, message: string, error: any, payload: LogPayload): void; - export function warn(context: LogContext, message: string, error: any): void; + export function warn(context: LogContext, message: string, error: unknown, payload: LogPayload): void; + export function warn(context: LogContext, message: string, error: unknown): void; export function warn(context: LogContext, message: string, payload: LogPayload): void; export function warn(context: LogContext, message: string): void; - export function warn(context: LogContext, error: any, payload: LogPayload): void; - export function warn(context: LogContext, error: any): void; - export function warn(message: string, error: any, payload: LogPayload): void; - export function warn(message: string, error: any): void; + export function warn(context: LogContext, error: unknown, payload: LogPayload): void; + export function warn(context: LogContext, error: unknown): void; + export function warn(message: string, error: unknown, payload: LogPayload): void; + export function warn(message: string, error: unknown): void; export function warn(message: string, payload: LogPayload): void; export function warn(message: string): void; - export function warn(error: any, payload: LogPayload): void; - export function warn(error: any): void; - export function warn(...args: any[]): void { + export function warn(error: unknown, payload: LogPayload): void; + export function warn(error: unknown): void; + export function warn(...args: unknown[]): void { warnLog(false, args); } - export function info(context: LogContext, message: string, error: any, payload: LogPayload): void; - export function info(context: LogContext, message: string, error: any): void; + export function info(context: LogContext, message: string, error: unknown, payload: LogPayload): void; + export function info(context: LogContext, message: string, error: unknown): void; export function info(context: LogContext, message: string, payload: LogPayload): void; export function info(context: LogContext, message: string): void; - export function info(context: LogContext, error: any, payload: LogPayload): void; - export function info(context: LogContext, error: any): void; - export function info(message: string, error: any, payload: LogPayload): void; - export function info(message: string, error: any): void; + export function info(context: LogContext, error: unknown, payload: LogPayload): void; + export function info(context: LogContext, error: unknown): void; + export function info(message: string, error: unknown, payload: LogPayload): void; + export function info(message: string, error: unknown): void; export function info(message: string, payload: LogPayload): void; export function info(message: string): void; - export function info(error: any, payload: LogPayload): void; - export function info(error: any): void; - export function info(...args: any[]): void { + export function info(error: unknown, payload: LogPayload): void; + export function info(error: unknown): void; + export function info(...args: unknown[]): void { infoLog(false, args); } - export function debug(context: LogContext, message: string, error: any, payload: LogPayload): void; - export function debug(context: LogContext, message: string, error: any): void; + export function debug(context: LogContext, message: string, error: unknown, payload: LogPayload): void; + export function debug(context: LogContext, message: string, error: unknown): void; export function debug(context: LogContext, message: string, payload: LogPayload): void; export function debug(context: LogContext, message: string): void; - export function debug(context: LogContext, error: any, payload: LogPayload): void; - export function debug(context: LogContext, error: any): void; - export function debug(message: string, error: any, payload: LogPayload): void; - export function debug(message: string, error: any): void; + export function debug(context: LogContext, error: unknown, payload: LogPayload): void; + export function debug(context: LogContext, error: unknown): void; + export function debug(message: string, error: unknown, payload: LogPayload): void; + export function debug(message: string, error: unknown): void; export function debug(message: string, payload: LogPayload): void; export function debug(message: string): void; - export function debug(error: any, payload: LogPayload): void; - export function debug(error: any): void; - export function debug(...args: any[]): void { + export function debug(error: unknown, payload: LogPayload): void; + export function debug(error: unknown): void; + export function debug(...args: unknown[]): void { debugLog(false, args); } @@ -125,16 +129,16 @@ export namespace log { export function setLogLevel(logLevel: LogrusLogLevel | undefined) { jsonLogging = true; - console.error = function (...args: any[]): void { + console.error = function (...args: unknown[]): void { errorLog(true, args); }; - console.warn = function (...args: any[]): void { + console.warn = function (...args: unknown[]): void { warnLog(true, args); }; - console.info = function (...args: any[]): void { + console.info = function (...args: unknown[]): void { infoLog(true, args); }; - console.debug = function (...args: any[]): void { + console.debug = function (...args: unknown[]): void { debugLog(true, args); }; @@ -168,25 +172,25 @@ export namespace log { } } -type DoLogFunction = (calledViaConsole: boolean, args: any[]) => void; +type DoLogFunction = (calledViaConsole: boolean, args: unknown[]) => void; let errorLog = doErrorLog; -function doErrorLog(calledViaConsole: boolean, args: any[]): void { +function doErrorLog(calledViaConsole: boolean, args: unknown[]): void { doLog(calledViaConsole, errorConsoleLog, "ERROR", args); } let warnLog = doWarnLog; -function doWarnLog(calledViaConsole: boolean, args: any[]): void { +function doWarnLog(calledViaConsole: boolean, args: unknown[]): void { doLog(calledViaConsole, warnConsoleLog, "WARNING", args); } let infoLog = doInfoLog; -function doInfoLog(calledViaConsole: boolean, args: any[]): void { +function doInfoLog(calledViaConsole: boolean, args: unknown[]): void { doLog(calledViaConsole, infoConsoleLog, "INFO", args); } let debugLog = doDebugLog; -function doDebugLog(calledViaConsole: boolean, args: any[]): void { +function doDebugLog(calledViaConsole: boolean, args: unknown[]): void { doLog(calledViaConsole, debugConsoleLog, "DEBUG", args); } @@ -242,8 +246,9 @@ namespace GoogleLogSeverity { }; } -function doLog(calledViaConsole: boolean, consoleLog: ConsoleLog, severity: GoogleLogSeverity, args: any[]): void { +function doLog(calledViaConsole: boolean, consoleLog: ConsoleLog, severity: GoogleLogSeverity, args: unknown[]): void { if (!jsonLogging) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument consoleLog(...args); return; } @@ -256,7 +261,7 @@ function doLog(calledViaConsole: boolean, consoleLog: ConsoleLog, severity: Goog let context: LogContext | undefined; let message: string | undefined; let error: Error | undefined; - let payloadArgs: any[]; + let payloadArgs: unknown[]; if (args[0] instanceof Error) { // console.xyz(Error, ...any) / log.xyz(Error) / log.xyz(Error, LogPayload) @@ -277,7 +282,7 @@ function doLog(calledViaConsole: boolean, consoleLog: ConsoleLog, severity: Goog // or when passing, by mistake, log.xyz instead of console.xyz to third-party code as a callback (*)) payloadArgs = args; } else { - context = args[0]; + context = args[0] instanceof Object ? args[0] : undefined; if (args[1] instanceof Error) { // log.xyz(LogContext, Error) / log.xyz(LogContext, Error, LogPayload) error = args[1]; @@ -310,7 +315,7 @@ function makeLogItem( context: LogContext | undefined, message: string | undefined, error: Error | undefined, - payloadArgs: any[], + payloadArgs: unknown[], calledViaConsole: boolean, ): string | undefined { if (context !== undefined && Object.keys(context).length == 0) { @@ -325,7 +330,8 @@ function makeLogItem( } payloadArgs = payloadArgs.map((arg) => scrubPayload(arg, plainLogging)); - const payload: any = payloadArgs.length == 0 ? undefined : payloadArgs.length == 1 ? payloadArgs[0] : payloadArgs; + const payload: unknown = + payloadArgs.length == 0 ? undefined : payloadArgs.length == 1 ? payloadArgs[0] : payloadArgs; const logItem = { // undefined fields get eliminated in JSON.stringify() ...reportedErrorEvent, @@ -366,7 +372,7 @@ function makeLogItem( return result; } -function scrubPayload(payload: any, plainLogging: boolean): any { +function scrubPayload(payload: T, plainLogging: boolean): T { if (plainLogging) { return payload; } @@ -375,8 +381,8 @@ function scrubPayload(payload: any, plainLogging: boolean): any { // See https://cloud.google.com/error-reporting/docs/formatting-error-messages // and https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report#ReportedErrorEvent -function makeReportedErrorEvent(error: Error | undefined) { - const result: any = { +function makeReportedErrorEvent(error: Error | undefined): {} { + const result = { // Serves as marker only "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", // This is useful for filtering in the UI @@ -384,21 +390,29 @@ function makeReportedErrorEvent(error: Error | undefined) { service: component || "", version: version || "", }, - }; - if (error) { // According to: https://cloud.google.com/error-reporting/docs/formatting-error-messages#json_representation - const stackTrace = error.stack; - if (stackTrace) { - result.stack_trace = stackTrace; - } - } + stack_trace: error?.stack, + }; return result; } -function makeLogItemStub(logItem: any): any { - const result: any = { +type LogItem = { + component?: string; + severity?: string; + time?: string; + environment?: string; + region?: string; + message?: string; + messageStub?: string; + errorStub?: string; + error?: unknown; + payload?: unknown; +}; + +function makeLogItemStub(logItem: LogItem): LogItem { + const result = { component: logItem.component, severity: logItem.severity, time: logItem.time, @@ -412,7 +426,7 @@ function makeLogItemStub(logItem: any): any { result.messageStub = logItem.message.substring(0, maxMessageStubLength) + " ... (too long, truncated)"; } } - if (logItem.error instanceof Error) { + if (logItem.error instanceof Error && logItem.error.stack) { if (logItem.error.stack.length <= maxErrorStubLength) { result.error = logItem.error.stack; } else { @@ -422,7 +436,7 @@ function makeLogItemStub(logItem: any): any { return result; } -function stringifyLogItem(logItem: any): string { +function stringifyLogItem(logItem: LogItem): string { try { return jsonStringifyWithErrors(logItem); } catch (err) { @@ -438,13 +452,13 @@ function stringifyLogItem(logItem: any): string { /** * Jsonifies Errors properly, not as {} only. */ -function jsonStringifyWithErrors(value: any): string { +function jsonStringifyWithErrors(value: unknown): string { return JSON.stringify(value, (_, value) => { return value instanceof Error ? value.stack : value; }); } -type ConsoleLog = (message?: any, ...optionalArgs: any[]) => void; // signature of console.xyz +type ConsoleLog = (message?: unknown, ...optionalArgs: unknown[]) => void; // signature of console.xyz const logConsoleLog: ConsoleLog = console.log; const errorConsoleLog: ConsoleLog = console.error; const warnConsoleLog: ConsoleLog = console.warn; diff --git a/components/gitpod-protocol/src/util/queue.spec.ts b/components/gitpod-protocol/src/util/queue.spec.ts index 81a7bb5ec6adea..8ceaee676c358f 100644 --- a/components/gitpod-protocol/src/util/queue.spec.ts +++ b/components/gitpod-protocol/src/util/queue.spec.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-floating-promises */ /** * Copyright (c) 2020 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/gitpod-protocol/src/util/scrubbing.ts b/components/gitpod-protocol/src/util/scrubbing.ts index 20f9ee1b2b3baf..985182d027f058 100644 --- a/components/gitpod-protocol/src/util/scrubbing.ts +++ b/components/gitpod-protocol/src/util/scrubbing.ts @@ -115,7 +115,7 @@ function doScrub(obj: any, depth: number, nested: boolean): any { } const objType = typeof obj; if (objType === "string") { - return scrubber.scrubValue(obj); + return scrubber.scrubValue(obj as string); } if (objType === "boolean" || objType === "number") { return obj; @@ -131,7 +131,7 @@ function doScrub(obj: any, depth: number, nested: boolean): any { } if (objType === "object") { const result: any = {}; - for (const [key, value] of Object.entries(obj)) { + for (const [key, value] of Object.entries(obj as object)) { if (typeof value === "string") { result[key] = scrubber.scrubKeyValue(key, value); } else { diff --git a/components/gitpod-protocol/src/util/tracing.ts b/components/gitpod-protocol/src/util/tracing.ts index bedb66985eea13..86f8fe1f238773 100644 --- a/components/gitpod-protocol/src/util/tracing.ts +++ b/components/gitpod-protocol/src/util/tracing.ts @@ -60,7 +60,7 @@ export namespace TraceContext { } } - export function setError(ctx: TraceContext, err: Error) { + export function setError(ctx: TraceContext, err: any) { if (!ctx.span) { return; } @@ -169,6 +169,7 @@ export namespace TraceContext { for (const k of Object.keys(keyValueMap)) { const v = keyValueMap[k]; if (v instanceof Object) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument addNestedTags(ctx, v, `${namespace}${k}`); } else { ctx.span.setTag(`${namespace}${k}`, v); @@ -223,6 +224,7 @@ export class TracingManager { if (opts) { if (opts.perOpSampling) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument (t as any)._sampler = new PerOperationSampler((t as any)._sampler, opts.perOpSampling); } } @@ -264,6 +266,7 @@ export class PerOperationSampler implements Sampler { onCreateSpan(span: opentracing.Span): SamplingDecision { const outTags = {}; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const isSampled = this.isSampled((span as any).operationName, outTags); // NB: return retryable=true here since we can change decision after setOperationName(). return { sample: isSampled, retryable: true, tags: outTags }; @@ -271,6 +274,7 @@ export class PerOperationSampler implements Sampler { onSetOperationName(span: opentracing.Span, operationName: string): SamplingDecision { const outTags = {}; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const isSampled = this.isSampled((span as any).operationName, outTags); return { sample: isSampled, retryable: false, tags: outTags }; } diff --git a/components/gitpod-protocol/src/workspace-cluster.ts b/components/gitpod-protocol/src/workspace-cluster.ts index 150775a5607aa2..c2f49912b32bdc 100644 --- a/components/gitpod-protocol/src/workspace-cluster.ts +++ b/components/gitpod-protocol/src/workspace-cluster.ts @@ -13,6 +13,7 @@ const workspaceRegions = ["europe", "north-america", "south-america", "africa", export type WorkspaceRegion = typeof workspaceRegions[number]; export function isWorkspaceRegion(s: string): s is WorkspaceRegion { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return workspaceRegions.indexOf(s as any) !== -1; } diff --git a/components/server/.eslintrc b/components/server/.eslintrc index 68c3320653bc5f..00a6d9b51df5f2 100644 --- a/components/server/.eslintrc +++ b/components/server/.eslintrc @@ -30,6 +30,7 @@ "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unused-vars": [ "error", { diff --git a/components/server/src/analytics.ts b/components/server/src/analytics.ts index 815e048bd4bc06..0bc74292709dcb 100644 --- a/components/server/src/analytics.ts +++ b/components/server/src/analytics.ts @@ -98,7 +98,7 @@ function getAnonymousId(request: Request) { if (!(request.cookies["gp-analytical"] === "true")) { return; } - return stripCookie(request.cookies.ajs_anonymous_id); + return stripCookie(request.cookies.ajs_anonymous_id as string); } function resolveIdentities(user: User) { diff --git a/components/server/src/api/server.ts b/components/server/src/api/server.ts index fbb0bf91dc815f..5eff0abd077dac 100644 --- a/components/server/src/api/server.ts +++ b/components/server/src/api/server.ts @@ -212,7 +212,8 @@ export class API { } private async verify(context: HandlerContext) { - const user = await this.sessionHandler.verify(context.requestHeader.get("cookie") || ""); + const cookieHeader: string = context.requestHeader.get("cookie") || ""; + const user = await this.sessionHandler.verify(cookieHeader); if (!user) { throw new ConnectError("unauthenticated", Code.Unauthenticated); } diff --git a/components/server/src/auth/bearer-authenticator.ts b/components/server/src/auth/bearer-authenticator.ts index cb7421bc2f3968..c1aa72bae4847b 100644 --- a/components/server/src/auth/bearer-authenticator.ts +++ b/components/server/src/auth/bearer-authenticator.ts @@ -32,7 +32,7 @@ const bearerAuthCode = "BearerAuth"; interface BearerAuthError extends Error { code: typeof bearerAuthCode; } -export function isBearerAuthError(error: Error): error is BearerAuthError { +export function isBearerAuthError(error: any): error is BearerAuthError { return "code" in error && (error as any)["code"] === bearerAuthCode; } function createBearerAuthError(message: string): BearerAuthError { diff --git a/components/server/src/auth/generic-auth-provider.ts b/components/server/src/auth/generic-auth-provider.ts index 60b11920c07627..44ee9783659762 100644 --- a/components/server/src/auth/generic-auth-provider.ts +++ b/components/server/src/auth/generic-auth-provider.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2020 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). @@ -371,7 +372,7 @@ export abstract class GenericAuthProvider implements AuthProvider { */ const context = LogContext.from({ - user: User.is(userOrIdentity) ? { userId: userOrIdentity.id } : undefined, + userId: User.is(userOrIdentity) ? userOrIdentity.id : undefined, request, }); diff --git a/components/server/src/bitbucket-server/bitbucket-server-api.spec.ts b/components/server/src/bitbucket-server/bitbucket-server-api.spec.ts index 40a68de2233628..a06fd02ff02057 100644 --- a/components/server/src/bitbucket-server/bitbucket-server-api.spec.ts +++ b/components/server/src/bitbucket-server/bitbucket-server-api.spec.ts @@ -40,6 +40,7 @@ class TestBitbucketServerApi { bind(BitbucketServerContextParser).toSelf().inSingletonScope(); bind(AuthProviderParams).toConstantValue(TestBitbucketServerApi.AUTH_HOST_CONFIG); bind(BitbucketServerTokenHelper).toSelf().inSingletonScope(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument bind(TokenService).toConstantValue({ createGitpodToken: async () => ({ token: { value: "foobar123-token" } }), } as any); diff --git a/components/server/src/bitbucket-server/bitbucket-server-context-parser.spec.ts b/components/server/src/bitbucket-server/bitbucket-server-context-parser.spec.ts index c6bd3d80e72c0a..7e8f49c6fd5b71 100644 --- a/components/server/src/bitbucket-server/bitbucket-server-context-parser.spec.ts +++ b/components/server/src/bitbucket-server/bitbucket-server-context-parser.spec.ts @@ -40,6 +40,7 @@ class TestBitbucketServerContextParser { bind(BitbucketServerContextParser).toSelf().inSingletonScope(); bind(AuthProviderParams).toConstantValue(TestBitbucketServerContextParser.AUTH_HOST_CONFIG); bind(BitbucketServerTokenHelper).toSelf().inSingletonScope(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument bind(TokenService).toConstantValue({ createGitpodToken: async () => ({ token: { value: "foobar123-token" } }), } as any); diff --git a/components/server/src/bitbucket-server/bitbucket-server-file-provider.spec.ts b/components/server/src/bitbucket-server/bitbucket-server-file-provider.spec.ts index 8c90ba70a0b7e7..7ba41572f06526 100644 --- a/components/server/src/bitbucket-server/bitbucket-server-file-provider.spec.ts +++ b/components/server/src/bitbucket-server/bitbucket-server-file-provider.spec.ts @@ -50,6 +50,7 @@ class TestBitbucketServerFileProvider { bind(BitbucketServerContextParser).toSelf().inSingletonScope(); bind(AuthProviderParams).toConstantValue(TestBitbucketServerFileProvider.AUTH_HOST_CONFIG); bind(BitbucketServerTokenHelper).toSelf().inSingletonScope(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument bind(TokenService).toConstantValue({ createGitpodToken: async () => ({ token: { value: "foobar123-token" } }), } as any); @@ -90,6 +91,7 @@ class TestBitbucketServerFileProvider { @test async test_getGitpodFileContent_ok() { const result = await this.service.getGitpodFileContent( + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument { revision: "master", repository: { diff --git a/components/server/src/bitbucket-server/bitbucket-server-repository-provider.spec.ts b/components/server/src/bitbucket-server/bitbucket-server-repository-provider.spec.ts index fd371211579771..218a6938ca3f88 100644 --- a/components/server/src/bitbucket-server/bitbucket-server-repository-provider.spec.ts +++ b/components/server/src/bitbucket-server/bitbucket-server-repository-provider.spec.ts @@ -50,6 +50,7 @@ class TestBitbucketServerRepositoryProvider { bind(BitbucketServerContextParser).toSelf().inSingletonScope(); bind(AuthProviderParams).toConstantValue(TestBitbucketServerRepositoryProvider.AUTH_HOST_CONFIG); bind(BitbucketServerTokenHelper).toSelf().inSingletonScope(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument bind(TokenService).toConstantValue({ createGitpodToken: async () => ({ token: { value: "foobar123-token" } }), } as any); diff --git a/components/server/src/bitbucket/bitbucket-auth-provider.ts b/components/server/src/bitbucket/bitbucket-auth-provider.ts index 80dcabdb1d013c..df1a0b885b5b04 100644 --- a/components/server/src/bitbucket/bitbucket-auth-provider.ts +++ b/components/server/src/bitbucket/bitbucket-auth-provider.ts @@ -77,6 +77,7 @@ export class BitbucketAuthProvider extends GenericAuthProvider { const primaryEmail = emails.values.find((x: { is_primary: boolean; email: string }) => x.is_primary).email; const currentScopes = this.normalizeScopes( + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument (headers as any)["x-oauth-scopes"].split(",").map((s: string) => s.trim()), ); diff --git a/components/server/src/github/api.ts b/components/server/src/github/api.ts index 537b6ac8ddef61..14f3e52ffd9408 100644 --- a/components/server/src/github/api.ts +++ b/components/server/src/github/api.ts @@ -27,7 +27,7 @@ export class GitHubApiError extends Error { } } export namespace GitHubApiError { - export function is(error: Error | null): error is GitHubApiError { + export function is(error: any): error is GitHubApiError { return !!error && error.name === "GitHubApiError"; } } @@ -198,7 +198,7 @@ export class GitHubRestApi { return response; } catch (error) { if (error.status) { - throw new GitHubApiError(error); + throw new GitHubApiError(error as OctokitResponse); } throw error; } finally { diff --git a/components/server/src/github/github-app-support.ts b/components/server/src/github/github-app-support.ts index f7c77b7538f7d2..ed113cf2ffa786 100644 --- a/components/server/src/github/github-app-support.ts +++ b/components/server/src/github/github-app-support.ts @@ -121,6 +121,7 @@ export class GitHubAppSupport { // If hints contain an additional installationId, let's try to add the repos // + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const installationId = parseInt((hints as any)?.installationId, 10); if (!isNaN(installationId)) { if (!result.some((r) => r.installationId === installationId)) { diff --git a/components/server/src/github/github-auth-provider.ts b/components/server/src/github/github-auth-provider.ts index c4ab45a23441cc..2c810abff0a73d 100644 --- a/components/server/src/github/github-auth-provider.ts +++ b/components/server/src/github/github-auth-provider.ts @@ -103,6 +103,7 @@ export class GitHubAuthProvider extends GenericAuthProvider { // https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/ // e.g. X-OAuth-Scopes: repo, user const currentScopes = this.normalizeScopes( + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument (headers as any)["x-oauth-scopes"].split(this.oauthConfig.scopeSeparator!).map((s: string) => s.trim()), ); diff --git a/components/server/src/github/github-context-parser.ts b/components/server/src/github/github-context-parser.ts index 92292df18fd601..3a8137302fecb0 100644 --- a/components/server/src/github/github-context-parser.ts +++ b/components/server/src/github/github-context-parser.ts @@ -234,6 +234,7 @@ export class GithubContextParser extends AbstractContextParser implements IConte if (repo.ref !== null) { return { ref: repo.ref.name, + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument refType: this.toRefType({ userId: user.id }, { host, owner, repoName }, repo.ref.prefix), isFile, path, diff --git a/components/server/src/gitlab/gitlab-auth-provider.ts b/components/server/src/gitlab/gitlab-auth-provider.ts index 32a9a11decc7e9..9ee945da460b3f 100644 --- a/components/server/src/gitlab/gitlab-auth-provider.ts +++ b/components/server/src/gitlab/gitlab-auth-provider.ts @@ -95,7 +95,7 @@ export class GitLabAuthProvider extends GenericAuthProvider { if (error && typeof error.description === "string" && error.description.includes("403 Forbidden")) { // If GitLab is configured to disallow OAuth-token based API access for unconfirmed users, we need to reject this attempt // 403 Forbidden - You (@...) must accept the Terms of Service in order to perform this action. Please access GitLab from a web browser to accept these terms. - throw UnconfirmedUserException.create(error.description, error); + throw UnconfirmedUserException.create(error.description as string, error); } else { log.error(`(${this.strategyName}) Reading current user info failed`, error, { accessToken, error }); throw error; @@ -105,7 +105,7 @@ export class GitLabAuthProvider extends GenericAuthProvider { protected readScopesFromVerifyParams(params: any) { if (params && typeof params.scope === "string") { - return this.normalizeScopes(params.scope.split(" ")); + return this.normalizeScopes((params.scope as string).split(" ")); } return []; } diff --git a/components/server/src/iam/iam-session-app.spec.ts b/components/server/src/iam/iam-session-app.spec.ts index dac57f3a3e118c..32c6d7f8ea169e 100644 --- a/components/server/src/iam/iam-session-app.spec.ts +++ b/components/server/src/iam/iam-session-app.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2022 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/server/src/init.ts b/components/server/src/init.ts index eb8f263809bf9a..f340ff00e9b63e 100644 --- a/components/server/src/init.ts +++ b/components/server/src/init.ts @@ -108,8 +108,8 @@ export async function start(container: Container) { const pool: any = (connection.driver as any).pool; interval = setInterval(async () => { try { - const activeConnections = pool._allConnections.length; - const freeConnections = pool._freeConnections.length; + const activeConnections = pool._allConnections.length as number; + const freeConnections = pool._freeConnections.length as number; dbConnectionsTotal.set(activeConnections); dbConnectionsFree.set(freeConnections); diff --git a/components/server/src/linkedin-service.ts b/components/server/src/linkedin-service.ts index c5b429268a3001..0658dd809662d6 100644 --- a/components/server/src/linkedin-service.ts +++ b/components/server/src/linkedin-service.ts @@ -45,7 +45,7 @@ export class LinkedInService { if (data.error) { throw new Error("Could not get LinkedIn access token: " + data.error_description); } - return data.access_token; + return data.access_token as string; } // Retrieve the user's profile from LinkedIn using the following API: @@ -96,12 +96,10 @@ export class LinkedInService { }; try { - if ( - typeof profileData.firstName?.localized === "object" && - Object.values(profileData.firstName?.localized).length > 0 - ) { + const localized = profileData.firstName?.localized; + if (typeof localized === "object" && Object.values(localized as object).length > 0) { // If there are multiple first name localizations, just pick the first one - profile.firstName = String(Object.values(profileData.firstName.localized)[0]); + profile.firstName = String(Object.values(localized as object)[0]); } } catch (error) { log.error("Error getting LinkedIn first name", error); @@ -110,10 +108,10 @@ export class LinkedInService { try { if ( typeof profileData.lastName?.localized === "object" && - Object.values(profileData.lastName?.localized).length > 0 + Object.values(profileData.lastName?.localized as object).length > 0 ) { // If there are multiple last name localizations, just pick the first one - profile.lastName = String(Object.values(profileData.lastName.localized)[0]); + profile.lastName = String(Object.values(profileData.lastName.localized as object)[0]); } } catch (error) { log.error("Error getting LinkedIn last name", error); diff --git a/components/server/src/messaging/redis-subscriber.ts b/components/server/src/messaging/redis-subscriber.ts index e847c7d8ac1350..580e3286b99f7b 100644 --- a/components/server/src/messaging/redis-subscriber.ts +++ b/components/server/src/messaging/redis-subscriber.ts @@ -146,11 +146,10 @@ export class RedisSubscriber { try { l(ctx, prebuildWithStatus); } catch (err) { - log.error( - "Failed to broadcast workspace instance update.", - { projectId: update.projectID, workspaceId: update.workspaceID }, - err, - ); + log.error("Failed to broadcast workspace instance update.", err, { + projectId: update.projectID, + workspaceId: update.workspaceID, + }); } } } @@ -172,7 +171,7 @@ export class RedisSubscriber { try { l(ctx, update); } catch (err) { - log.error("Failed to broadcast headless update.", update, err); + log.error("Failed to broadcast headless update.", err, update); } } } diff --git a/components/server/src/monitoring-endpoints.ts b/components/server/src/monitoring-endpoints.ts index 3f40cbda92407f..8a4c0d59e2f9b7 100644 --- a/components/server/src/monitoring-endpoints.ts +++ b/components/server/src/monitoring-endpoints.ts @@ -22,6 +22,7 @@ export class MonitoringEndpointsApp { // Append redis metrics to default registry redisMetricsRegistry() .getMetricsAsArray() + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument .forEach((metric) => registry.registerMetric(metric as any)); const monApp = express(); diff --git a/components/server/src/orgs/organization-service.ts b/components/server/src/orgs/organization-service.ts index 291a595c4d0eba..6cfa8bf00cc4b9 100644 --- a/components/server/src/orgs/organization-service.ts +++ b/components/server/src/orgs/organization-service.ts @@ -313,7 +313,8 @@ export class OrganizationService { await this.auth.addOrganizationRole(orgId, memberId, membership.role); } const code = ApplicationError.hasErrorCode(err) ? err.code : ErrorCodes.INTERNAL_SERVER_ERROR; - throw new ApplicationError(code, err); + const message = ApplicationError.hasErrorCode(err) ? err.message : "" + err; + throw new ApplicationError(code, message); } this.analytics.track({ userId, diff --git a/components/server/src/prebuilds/bitbucket-app.ts b/components/server/src/prebuilds/bitbucket-app.ts index f071e8af168934..2ac38a3aa61a45 100644 --- a/components/server/src/prebuilds/bitbucket-app.ts +++ b/components/server/src/prebuilds/bitbucket-app.ts @@ -62,6 +62,7 @@ export class BitbucketApp { return; } try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const data = toData(req.body); if (data) { await this.handlePushHook({ span }, data, user, event); diff --git a/components/server/src/prebuilds/bitbucket-server-app.ts b/components/server/src/prebuilds/bitbucket-server-app.ts index fc65a174a6fd0c..d5706726fb0130 100644 --- a/components/server/src/prebuilds/bitbucket-server-app.ts +++ b/components/server/src/prebuilds/bitbucket-server-app.ts @@ -62,6 +62,7 @@ export class BitbucketServerApp { return; } try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument await this.handlePushHook({ span }, user, payload, event); } catch (err) { TraceContext.setError({ span }, err); diff --git a/components/server/src/prebuilds/bitbucket-server-service.spec.ts b/components/server/src/prebuilds/bitbucket-server-service.spec.ts index 0c24a8e04dacc8..0d0883296d1f10 100644 --- a/components/server/src/prebuilds/bitbucket-server-service.spec.ts +++ b/components/server/src/prebuilds/bitbucket-server-service.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2022 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/server/src/prebuilds/github-app.ts b/components/server/src/prebuilds/github-app.ts index e8773a1e4529a6..ecdee252bfdea1 100644 --- a/components/server/src/prebuilds/github-app.ts +++ b/components/server/src/prebuilds/github-app.ts @@ -570,7 +570,7 @@ export class GithubApp { const newBody = body + `\n\n${button}\n\n`; const updatePrPromise = ctx.octokit.pulls.update({ ...ctx.repo(), pull_number: pr.number, body: newBody }); - updatePrPromise.catch((err) => log.error(err, "Error while updating PR body", { contextURL })); + updatePrPromise.catch((err) => log.error("Error while updating PR body", err, { contextURL })); } private async onPrAddComment( @@ -594,7 +594,7 @@ export class GithubApp { const newComment = ctx.issue({ body: `\n\n${button}\n\n` }); const newCommentPromise = ctx.octokit.issues.createComment(newComment); - newCommentPromise.catch((err) => log.error(err, "Error while adding new PR comment", { contextURL })); + newCommentPromise.catch((err) => log.error("Error while adding new PR comment", err, { contextURL })); } private getBadgeImageURL(): string { diff --git a/components/server/src/prebuilds/github-enterprise-app.ts b/components/server/src/prebuilds/github-enterprise-app.ts index 412deacf839934..9b185b0d224e4f 100644 --- a/components/server/src/prebuilds/github-enterprise-app.ts +++ b/components/server/src/prebuilds/github-enterprise-app.ts @@ -124,6 +124,7 @@ export class GitHubEnterpriseApp { const sig = "sha256=" + createHmac("sha256", user.id + "|" + tokenEntry.token.value) + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument .update(body) .digest("hex"); return timingSafeEqual(Buffer.from(sig), Buffer.from(signature ?? "")); diff --git a/components/server/src/prebuilds/prebuild-manager.spec.ts b/components/server/src/prebuilds/prebuild-manager.spec.ts index 2f196817ee3173..7391739f0b109f 100644 --- a/components/server/src/prebuilds/prebuild-manager.spec.ts +++ b/components/server/src/prebuilds/prebuild-manager.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2023 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/server/src/server.ts b/components/server/src/server.ts index 74e5f213312c6d..1e360a3777ab16 100644 --- a/components/server/src/server.ts +++ b/components/server/src/server.ts @@ -112,7 +112,7 @@ export class Server { const startTime = Date.now(); req.on("end", () => { const method = req.method; - const route = req.route?.path || req.baseUrl || "unknown"; + const route = String(req.route?.path || req.baseUrl || "unknown"); observeHttpRequestDuration(method, route, res.statusCode, (Date.now() - startTime) / 1000); increaseHttpRequestCounter(method, route, res.statusCode); }); @@ -162,6 +162,7 @@ export class Server { // We rely on the origin header being set correctly (needed by regular clients to use Gitpod: // CORS allows subdomains to access gitpod.io) const verifyOrigin = (origin: string) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument let allowedRequest = isAllowedWebsocketDomain(origin, this.config.hostUrl.url.hostname); if (!allowedRequest && this.config.insecureNoDomain) { log.warn("Websocket connection CSRF guard disabled"); @@ -217,6 +218,7 @@ export class Server { ); const wsPingPongHandler = new WsConnectionHandler(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const wsHandler = new WsExpressHandler(httpServer, verifyClient); this.disposables.push(wsHandler); wsHandler.ws( @@ -229,6 +231,7 @@ export class Server { ...initSessionHandlers, wsPingPongHandler.handler(), (ws: WebSocket, req: express.Request) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument websocketConnectionHandler.onConnection((req as any).wsConnection, req); }, ); @@ -240,6 +243,7 @@ export class Server { }, wsPingPongHandler.handler(), (ws: WebSocket, req: express.Request) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument websocketConnectionHandler.onConnection((req as any).wsConnection, req); }, ); diff --git a/components/server/src/test/service-testing-container-module.ts b/components/server/src/test/service-testing-container-module.ts index 72a44645d71796..e3af0b690aad14 100644 --- a/components/server/src/test/service-testing-container-module.ts +++ b/components/server/src/test/service-testing-container-module.ts @@ -107,7 +107,7 @@ const mockApplyingContainerModule = new ContainerModule((bind, unbound, isbound, }, services: { repositoryService: { - installAutomatedPrebuilds: async (user: any, cloneUrl: any) => { + installAutomatedPrebuilds: async (user: any, cloneUrl: string) => { webhooks.add(cloneUrl); }, canInstallAutomatedPrebuilds: async () => { diff --git a/components/server/src/user/user-controller.ts b/components/server/src/user/user-controller.ts index 49c58bc2e26275..efe4f33eb42a53 100644 --- a/components/server/src/user/user-controller.ts +++ b/components/server/src/user/user-controller.ts @@ -643,6 +643,7 @@ export class UserController { throw err; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return new AdminCredentials(payload.tokenHash, payload.expiresAt, payload.algo); } } diff --git a/components/server/src/user/user-deletion-service.ts b/components/server/src/user/user-deletion-service.ts index ca678d78e3b5c0..f141864593ddbd 100644 --- a/components/server/src/user/user-deletion-service.ts +++ b/components/server/src/user/user-deletion-service.ts @@ -14,6 +14,7 @@ import { AuthProviderService } from "../auth/auth-provider-service"; import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics"; import { WorkspaceService } from "../workspace/workspace-service"; import { Authorizer } from "../authorization/authorizer"; +import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error"; @injectable() export class UserDeletionService { @@ -39,7 +40,7 @@ export class UserDeletionService { await this.authorizer.checkPermissionOnUser(userId, "delete", targetUserId); const user = await this.db.findUserById(targetUserId); if (!user) { - throw new Error(`No user with id ${targetUserId} found!`); + throw new ApplicationError(ErrorCodes.NOT_FOUND, `No user with id ${targetUserId} found!`); } if (user.markedDeleted === true) { diff --git a/components/server/src/user/user-service.ts b/components/server/src/user/user-service.ts index a6f8450c88769f..9e565e07ca9514 100644 --- a/components/server/src/user/user-service.ts +++ b/components/server/src/user/user-service.ts @@ -142,7 +142,7 @@ export class UserService { try { WorkspaceTimeoutDuration.validate(setting.workspaceTimeout); } catch (err) { - throw new ApplicationError(ErrorCodes.BAD_REQUEST, err.message); + throw new ApplicationError(ErrorCodes.BAD_REQUEST, String(err)); } } @@ -179,8 +179,8 @@ export class UserService { } } return result; - } catch (e) { - throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString()); + } catch (err) { + throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, String(err)); } } diff --git a/components/server/src/websocket/websocket-connection-manager.ts b/components/server/src/websocket/websocket-connection-manager.ts index 9105c7d0c2e7c8..85f2d841d87e45 100644 --- a/components/server/src/websocket/websocket-connection-manager.ts +++ b/components/server/src/websocket/websocket-connection-manager.ts @@ -386,6 +386,7 @@ class GitpodJsonRpcProxyFactory extends JsonRpcProxyFactory }, () => { try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return this.internalOnRequest(span, requestId, method, ...args); } finally { span.finish(); @@ -475,7 +476,7 @@ class GitpodJsonRpcProxyFactory extends JsonRpcProxyFactory TraceContext.setJsonRPCError(ctx, method, err, true); log.error({ userId }, `Request ${method} failed with internal server error`, e, { method, args }); - throw new ResponseError(ErrorCodes.INTERNAL_SERVER_ERROR, e.message); + throw new ResponseError(ErrorCodes.INTERNAL_SERVER_ERROR, String(e)); } } } diff --git a/components/server/src/workspace/config-provider.spec.ts b/components/server/src/workspace/config-provider.spec.ts index 8f1933c3c7e03d..6565b00f491dfb 100644 --- a/components/server/src/workspace/config-provider.spec.ts +++ b/components/server/src/workspace/config-provider.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2023 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/server/src/workspace/config-provider.ts b/components/server/src/workspace/config-provider.ts index a1cbd0776664ce..abca87436630fd 100644 --- a/components/server/src/workspace/config-provider.ts +++ b/components/server/src/workspace/config-provider.ts @@ -312,7 +312,7 @@ export class InvalidGitpodYMLError extends Error { } export namespace InvalidGitpodYMLError { - export function is(obj: object): obj is InvalidGitpodYMLError { + export function is(obj: any): obj is InvalidGitpodYMLError { return "errorType" in obj && (obj as any).errorType === "invalidGitpodYML" && "validationErrors" in obj; } } diff --git a/components/server/src/workspace/envvar-prefix-context-parser.spec.ts b/components/server/src/workspace/envvar-prefix-context-parser.spec.ts index a1c1d45497faf6..96a8f3b110de89 100644 --- a/components/server/src/workspace/envvar-prefix-context-parser.spec.ts +++ b/components/server/src/workspace/envvar-prefix-context-parser.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /** * Copyright (c) 2021 Gitpod GmbH. All rights reserved. * Licensed under the GNU Affero General Public License (AGPL). diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts index 5d23971680b1b4..c1ef383efa97bc 100644 --- a/components/server/src/workspace/gitpod-server-impl.ts +++ b/components/server/src/workspace/gitpod-server-impl.ts @@ -1297,15 +1297,14 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { throw new ApplicationError(ErrorCodes.INVALID_GITPOD_YML, error.message); } - const errorCode = this.parseErrorCode(error); - if (errorCode) { + if (ApplicationError.hasErrorCode(error)) { // specific errors will be handled in create-workspace.tsx throw error; } log.debug(logContext, error); throw new ApplicationError( ErrorCodes.CONTEXT_PARSE_ERROR, - error && error.message ? error.message : `Cannot create workspace for URL: ${normalizedContextUrl}`, + error ? String(error) : `Cannot create workspace for URL: ${normalizedContextUrl}`, ); } @@ -1421,19 +1420,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { return prebuild; } - private parseErrorCode(error: any) { - const errorCode = error && error.code; - if (errorCode) { - try { - const code = parseInt(errorCode); - if (!isNaN(code)) { - return code; - } - } catch {} - } - return undefined; - } - public async getFeaturedRepositories(ctx: TraceContext): Promise { const user = await this.checkAndBlockUser("getFeaturedRepositories"); const repositories = await this.workspaceDb.trace(ctx).getFeaturedRepositories(); @@ -2017,7 +2003,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { await this.snapshotService.waitForSnapshot(opts); } catch (err) { // wrap in SNAPSHOT_ERROR to signal this call should not be retried. - throw new ApplicationError(ErrorCodes.SNAPSHOT_ERROR, err.toString()); + throw new ApplicationError(ErrorCodes.SNAPSHOT_ERROR, String(err)); } } @@ -2645,7 +2631,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { ); return res; } catch (e) { - throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString()); + throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, String(e)); } } @@ -2703,11 +2689,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { const admin = await this.guardAdminAccess("adminDeleteUser", { id: userId }, Permission.ADMIN_PERMISSIONS); - try { - await this.userDeletionService.deleteUser(admin.id, userId); - } catch (e) { - throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString()); - } + await this.userDeletionService.deleteUser(admin.id, userId); } async adminVerifyUser(ctx: TraceContext, userId: string): Promise { @@ -2979,7 +2961,10 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { const result = await this.authProviderService.updateAuthProvider(safeProvider); return AuthProviderEntry.redact(result); } catch (error) { - const message = error && error.message ? error.message : "Failed to update the provider."; + if (ApplicationError.hasErrorCode(error)) { + throw error; + } + const message = error ? String(error) : "Failed to update the provider."; throw new ApplicationError(ErrorCodes.CONFLICT, message); } } @@ -3011,12 +2996,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { if (!authProvider) { throw new ApplicationError(ErrorCodes.NOT_FOUND, "User resource not found."); } - try { - await this.authProviderService.deleteAuthProvider(authProvider); - } catch (error) { - const message = error && error.message ? error.message : "Failed to delete the provider."; - throw new ApplicationError(ErrorCodes.CONFLICT, message); - } + await this.authProviderService.deleteAuthProvider(authProvider); } async createOrgAuthProvider( @@ -3072,8 +3052,11 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { const result = await this.authProviderService.createOrgAuthProvider(newProvider); return AuthProviderEntry.redact(result); } catch (error) { - const message = error && error.message ? error.message : "Failed to create the provider."; - throw new ApplicationError(ErrorCodes.CONFLICT, message); + if (ApplicationError.hasErrorCode(error)) { + throw error; + } + const message = error ? String(error) : "Failed to create the provider."; + throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, message); } } @@ -3106,7 +3089,10 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { const result = await this.authProviderService.updateOrgAuthProvider(providerUpdate); return AuthProviderEntry.redact(result); } catch (error) { - const message = error && error.message ? error.message : "Failed to update the provider."; + if (ApplicationError.hasErrorCode(error)) { + throw error; + } + const message = error ? String(error) : "Failed to update the provider."; throw new ApplicationError(ErrorCodes.CONFLICT, message); } } @@ -3128,8 +3114,10 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { const result = await this.authProviderService.getAuthProvidersOfOrg(params.organizationId); return result.map(AuthProviderEntry.redact.bind(AuthProviderEntry)); } catch (error) { - const message = - error && error.message ? error.message : "Error retreiving auth providers for organization."; + if (ApplicationError.hasErrorCode(error)) { + throw error; + } + const message = error ? String(error) : "Error retreiving auth providers for organization."; throw new ApplicationError(ErrorCodes.INTERNAL_SERVER_ERROR, message); } } @@ -3156,12 +3144,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { throw new ApplicationError(ErrorCodes.NOT_FOUND, "Provider resource not found."); } - try { - await this.authProviderService.deleteAuthProvider(authProvider); - } catch (error) { - const message = error && error.message ? error.message : "Failed to delete the provider."; - throw new ApplicationError(ErrorCodes.CONFLICT, message); - } + await this.authProviderService.deleteAuthProvider(authProvider); } async getOnboardingState(ctx: TraceContext): Promise { diff --git a/components/server/src/workspace/workspace-service.ts b/components/server/src/workspace/workspace-service.ts index 39f55f7364b888..237c483ee404e9 100644 --- a/components/server/src/workspace/workspace-service.ts +++ b/components/server/src/workspace/workspace-service.ts @@ -791,6 +791,7 @@ export class WorkspaceService { chunk = chunk.replace("\n", WorkspaceImageBuild.LogLine.DELIMITER); lineCount += chunk.split(WorkspaceImageBuild.LogLine.DELIMITER_REGEX).length; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument client.onWorkspaceImageBuildLogs(undefined as any, { text: chunk, isDiff: true, @@ -911,7 +912,7 @@ export class WorkspaceService { } // TODO(gpl) Make private after FGA rollout -export function mapGrpcError(err: Error): Error { +export function mapGrpcError(err: any): Error { if (!isGrpcError(err)) { return err; } diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts index 935f6b79a847f9..d1225954fb56e9 100644 --- a/components/server/src/workspace/workspace-starter.ts +++ b/components/server/src/workspace/workspace-starter.ts @@ -179,7 +179,7 @@ export async function getWorkspaceClassForInstance( } class StartInstanceError extends Error { - constructor(public readonly reason: FailedInstanceStartReason, public readonly cause: Error) { + constructor(public readonly reason: FailedInstanceStartReason, public readonly cause: any) { super("Starting workspace instance failed: " + cause.message); } } @@ -778,7 +778,7 @@ export class WorkspaceStarter { */ private async failInstanceStart( ctx: TraceContext, - err: Error, + err: any, workspace: Workspace, instance: WorkspaceInstance, abortSignal: RedlockAbortSignal, @@ -819,7 +819,7 @@ export class WorkspaceStarter { } } - private async failPrebuildWorkspace(ctx: TraceContext, err: Error, workspace: Workspace) { + private async failPrebuildWorkspace(ctx: TraceContext, err: any, workspace: Workspace) { const span = TraceContext.startSpan("failInstanceStart", ctx); try { if (workspace.type === "prebuild") {