diff --git a/packages/rank/src/utils.ts b/packages/rank/src/utils.ts index 99a65a2c2f..b6654052ad 100644 --- a/packages/rank/src/utils.ts +++ b/packages/rank/src/utils.ts @@ -34,19 +34,23 @@ export function genRanks (count: number): Rank[] { /** @public */ export function makeRank (prev: Rank | undefined, next: Rank | undefined): Rank { - if (prev !== undefined && next !== undefined) { - const prevLexoRank = LexoRank.parse(prev) - const nextLexoRank = LexoRank.parse(next) - return prevLexoRank.equals(nextLexoRank) - ? prevLexoRank.genNext().toString() - : prevLexoRank.between(nextLexoRank).toString() - } else if (prev !== undefined) { - const prevLexoRank = LexoRank.parse(prev) - return prevLexoRank.genNext().toString() - } else if (next !== undefined) { - const nextLexoRank = LexoRank.parse(next) - return nextLexoRank.genPrev().toString() - } else { - return LexoRank.middle().toString() + try { + if (prev !== undefined && next !== undefined) { + const prevLexoRank = LexoRank.parse(prev) + const nextLexoRank = LexoRank.parse(next) + return prevLexoRank.equals(nextLexoRank) + ? prevLexoRank.genNext().toString() + : prevLexoRank.between(nextLexoRank).toString() + } else if (prev !== undefined) { + const prevLexoRank = LexoRank.parse(prev) + return prevLexoRank.genNext().toString() + } else if (next !== undefined) { + const nextLexoRank = LexoRank.parse(next) + return nextLexoRank.genPrev().toString() + } else { + return LexoRank.middle().toString() + } + } catch (err: any) { + throw new Error(`Failed to make rank: ${prev} ${next} ${err.message}`) } } diff --git a/services/github/pod-github/src/platform.ts b/services/github/pod-github/src/platform.ts index 0a127318c4..5aa3b3ccbd 100644 --- a/services/github/pod-github/src/platform.ts +++ b/services/github/pod-github/src/platform.ts @@ -674,7 +674,7 @@ export class PlatformWorker { } async getAccountByRef (workspace: WorkspaceUuid, ref: PersonId): Promise { - return await this.userManager.getAccountByRef(workspace, ref) + return await this.userManager.getAccountByRef(this.ctx, workspace, ref) } private async updateInstallation (installationId: number): Promise { diff --git a/services/github/pod-github/src/sync/pullrequests.ts b/services/github/pod-github/src/sync/pullrequests.ts index b5e1bec54a..fa3710ed6e 100644 --- a/services/github/pod-github/src/sync/pullrequests.ts +++ b/services/github/pod-github/src/sync/pullrequests.ts @@ -438,7 +438,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS pullRequestExternal.body ) - const op = this.client.apply() + let op = this.client.apply() let createdPullRequest: GithubPullRequest | undefined await this.ctx.withLog( @@ -464,17 +464,22 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS { url: pullRequestExternal.url } ) + await op.commit() const pullRequestObj = createdPullRequest ?? (await this.client.findOne(github.class.GithubPullRequest, { _id: info._id as unknown as Ref })) if (pullRequestObj !== undefined) { - await this.todoSync(op, pullRequestObj, pullRequestExternal, info, account) + op = this.client.apply() + try { + await this.todoSync(op, pullRequestObj, pullRequestExternal, info, account) + } catch (err: any) { + this.ctx.error('failed to sync todos', { err, url: pullRequestExternal.url, id: pullRequestObj._id }) + } + await op.commit() } - await op.commit() - // To sync reviews/review threads in case they are created before us. await syncChilds(info, this.client, derivedClient) @@ -555,7 +560,11 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS async afterSync (existing: Issue, account: PersonId, issueExternal: any, info: DocSyncInfo): Promise { const pullRequest = existing as GithubPullRequest - await this.todoSync(this.client, pullRequest, issueExternal as PullRequestExternalData, info, account) + try { + await this.todoSync(this.client, pullRequest, issueExternal as PullRequestExternalData, info, account) + } catch (err: any) { + this.ctx.error('failed to sync todos', { err, url: issueExternal.url, id: pullRequest._id }) + } } async todoSync ( diff --git a/services/github/pod-github/src/users.ts b/services/github/pod-github/src/users.ts index 72d5079b6b..6500a2fc2c 100644 --- a/services/github/pod-github/src/users.ts +++ b/services/github/pod-github/src/users.ts @@ -1,5 +1,5 @@ import type { AccountClient, IntegrationSecret } from '@hcengineering/account-client' -import core, { systemAccountUuid, type PersonId, type WorkspaceUuid } from '@hcengineering/core' +import core, { systemAccountUuid, type MeasureContext, type PersonId, type WorkspaceUuid } from '@hcengineering/core' import { getAccountClient } from '@hcengineering/server-client' import { generateToken } from '@hcengineering/server-token' import type { GithubUserRecord } from './types' @@ -43,7 +43,12 @@ export class UserManager { } } - async getAccountByRef (workspace: WorkspaceUuid, ref: PersonId): Promise { + failedRefs = new Set() + async getAccountByRef ( + ctx: MeasureContext, + workspace: WorkspaceUuid, + ref: PersonId + ): Promise { const key = `${workspace}.${ref}` let rec = this.refUserCache.get(key) if (rec !== undefined) { @@ -53,17 +58,26 @@ export class UserManager { return undefined } - const secrets = await this.accountClient.listIntegrationsSecrets({ kind: 'github-user', socialId: ref }) - if (secrets.length === 0) { - return - } - - rec = this.secretToUserRecord(secrets[0], secrets[0].key) - if (rec !== undefined) { - if (this.refUserCache.size > 1000) { - this.refUserCache.clear() + try { + if (this.failedRefs.has(ref)) { + // Ignore failed refs + return } - this.refUserCache.set(key, rec) + const secrets = await this.accountClient.listIntegrationsSecrets({ kind: 'github-user', socialId: ref }) + if (secrets.length === 0) { + return + } + + rec = this.secretToUserRecord(secrets[0], secrets[0].key) + if (rec !== undefined) { + if (this.refUserCache.size > 1000) { + this.refUserCache.clear() + } + this.refUserCache.set(key, rec) + } + } catch (err: any) { + this.failedRefs.add(ref) + ctx.warn('failed to get user by ref', { workspace, ref, err }) } return rec } diff --git a/services/github/pod-github/src/worker.ts b/services/github/pod-github/src/worker.ts index 5c18d4eb97..adbe44e492 100644 --- a/services/github/pod-github/src/worker.ts +++ b/services/github/pod-github/src/worker.ts @@ -1476,7 +1476,7 @@ export class GithubWorker implements IntegrationManager { 'sync doc', {}, (ctx) => mapper.sync(existing, info, parent, derivedClient), - { url: info.url.toLowerCase(), workspace: this.workspace.uuid } + { url: info.url.toLowerCase(), workspace: this.workspace.uuid, existing: existing !== undefined } ) if (docUpdate !== undefined) { await derivedClient.update(info, docUpdate)