From 643ec121a7afa3e5ac87c815f028e3a4c4832405 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Wed, 13 May 2026 15:14:06 +0200 Subject: [PATCH] `[twenty-server]` no-misused-promise lint (#20529) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Introduction Adding `no-miused-promise` lint rule to the twenty-server In order to flag such pattern ```ts // ❌ Flagged — forEach doesn't await the callback items.forEach(async (item) => { await process(item); }); ``` ## What happened - Refactored the code-interpreter driver to have a async onResult ( which is also expected by e2b ) - Workspace manager still dirty solution including force cast - Basic fixes --- packages/twenty-server/.oxlintrc.json | 1 + .../core-modules/auth/strategies/oidc.auth.strategy.ts | 2 +- .../cache-storage/services/cache-storage.service.ts | 2 +- .../core-modules/code-interpreter/drivers/e2b.driver.ts | 6 +++--- .../drivers/interfaces/code-interpreter-driver.interface.ts | 2 +- .../core-modules/code-interpreter/drivers/local.driver.ts | 2 +- .../tools/code-interpreter-tool/code-interpreter-tool.ts | 2 +- .../utils/wrap-async-iterator-with-lifecycle.ts | 4 ++-- .../twenty-orm/entity-manager/workspace-entity-manager.ts | 4 ++++ 9 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/twenty-server/.oxlintrc.json b/packages/twenty-server/.oxlintrc.json index 8973834fac..a1975b8866 100644 --- a/packages/twenty-server/.oxlintrc.json +++ b/packages/twenty-server/.oxlintrc.json @@ -57,6 +57,7 @@ "typescript/no-empty-function": "off", "typescript/no-explicit-any": "warn", "typescript/no-floating-promises": "error", + "typescript/no-misused-promises": "error", "typescript/no-unused-vars": ["warn", { "vars": "all", "varsIgnorePattern": "^_", diff --git a/packages/twenty-server/src/engine/core-modules/auth/strategies/oidc.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/oidc.auth.strategy.ts index 62c6e9c908..f2210d3969 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/strategies/oidc.auth.strategy.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/strategies/oidc.auth.strategy.ts @@ -47,7 +47,7 @@ export class OIDCAuthStrategy extends PassportStrategy( } // oxlint-disable-next-line @typescripttypescript/no-explicit-any - async authenticate(req: Request, options: any) { + authenticate(req: Request, options: any) { return super.authenticate(req, { ...options, state: JSON.stringify({ diff --git a/packages/twenty-server/src/engine/core-modules/cache-storage/services/cache-storage.service.ts b/packages/twenty-server/src/engine/core-modules/cache-storage/services/cache-storage.service.ts index 86545a983f..9ed6d0e023 100644 --- a/packages/twenty-server/src/engine/core-modules/cache-storage/services/cache-storage.service.ts +++ b/packages/twenty-server/src/engine/core-modules/cache-storage/services/cache-storage.service.ts @@ -134,7 +134,7 @@ export class CacheStorageService { async countAllSetMembers(cacheKeys: string[]) { return ( - await Promise.all(cacheKeys.map((key) => this.getSetLength(key) || 0)) + await Promise.all(cacheKeys.map((key) => this.getSetLength(key))) ).reduce((acc, setLength) => acc + setLength, 0); } diff --git a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/e2b.driver.ts b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/e2b.driver.ts index 9dab0de716..e5e342fc48 100644 --- a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/e2b.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/e2b.driver.ts @@ -96,7 +96,7 @@ export class E2BDriver implements CodeInterpreterDriver { const execution = await sbx.runCode(envSetup + code, { onStdout: (data) => callbacks?.onStdout?.(data.line), onStderr: (data) => callbacks?.onStderr?.(data.line), - onResult: (result) => { + onResult: async (result) => { if (result.png) { const outputFile: OutputFile = { filename: `chart-${chartCounter++}.png`, @@ -105,7 +105,7 @@ export class E2BDriver implements CodeInterpreterDriver { }; outputFiles.push(outputFile); - callbacks?.onResult?.(outputFile); + await callbacks?.onResult?.(outputFile); } }, }); @@ -126,7 +126,7 @@ export class E2BDriver implements CodeInterpreterDriver { }; outputFiles.push(outputFile); - callbacks?.onResult?.(outputFile); + await callbacks?.onResult?.(outputFile); } } } catch { diff --git a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/interfaces/code-interpreter-driver.interface.ts b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/interfaces/code-interpreter-driver.interface.ts index d3ee29ac51..be2f5a51b7 100644 --- a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/interfaces/code-interpreter-driver.interface.ts +++ b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/interfaces/code-interpreter-driver.interface.ts @@ -25,7 +25,7 @@ export type ExecutionContext = { export type StreamCallbacks = { onStdout?: (line: string) => void; onStderr?: (line: string) => void; - onResult?: (result: OutputFile) => void; + onResult?: (result: OutputFile) => Promise; }; export interface CodeInterpreterDriver { diff --git a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/local.driver.ts b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/local.driver.ts index 44ce795018..2ae24608d4 100644 --- a/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/local.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/code-interpreter/drivers/local.driver.ts @@ -111,7 +111,7 @@ export class LocalDriver implements CodeInterpreterDriver { }; outputFiles.push(outputFile); - callbacks?.onResult?.(outputFile); + await callbacks?.onResult?.(outputFile); } } } catch { diff --git a/packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/code-interpreter-tool.ts b/packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/code-interpreter-tool.ts index 2ef0b4a032..b30a5f122b 100644 --- a/packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/code-interpreter-tool.ts +++ b/packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/code-interpreter-tool.ts @@ -32,9 +32,9 @@ import { type CodeInterpreterFileInput, type CodeInterpreterInput, } from 'src/engine/core-modules/tool/tools/code-interpreter-tool/types/code-interpreter-input.type'; +import { type ToolExecutionContext } from 'src/engine/core-modules/tool/types/tool-execution-context.type'; import { type ToolInput } from 'src/engine/core-modules/tool/types/tool-input.type'; import { type ToolOutput } from 'src/engine/core-modules/tool/types/tool-output.type'; -import { type ToolExecutionContext } from 'src/engine/core-modules/tool/types/tool-execution-context.type'; import { type Tool } from 'src/engine/core-modules/tool/types/tool.type'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { AuthProviderEnum } from 'src/engine/core-modules/workspace/types/workspace.type'; diff --git a/packages/twenty-server/src/engine/subscriptions/utils/wrap-async-iterator-with-lifecycle.ts b/packages/twenty-server/src/engine/subscriptions/utils/wrap-async-iterator-with-lifecycle.ts index 47583feb8f..fb182cf5bd 100644 --- a/packages/twenty-server/src/engine/subscriptions/utils/wrap-async-iterator-with-lifecycle.ts +++ b/packages/twenty-server/src/engine/subscriptions/utils/wrap-async-iterator-with-lifecycle.ts @@ -17,9 +17,9 @@ export function wrapAsyncIteratorWithLifecycle( const startHeartbeat = () => { if (onHeartbeat && heartbeatIntervalMs) { - heartbeatInterval = setInterval(async () => { + heartbeatInterval = setInterval(() => { try { - await onHeartbeat(); + void onHeartbeat().catch(() => {}); } catch { // Heartbeat failure shouldn't crash the stream } diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts index 232dd5809d..b2144c241d 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts @@ -1280,6 +1280,7 @@ export class WorkspaceEntityManager extends EntityManager { ) .execute() .then(() => formattedEntityOrEntities as Entity[]) + // oxlint-disable-next-line @typescripttypescript/no-misused-promises .finally(() => queryRunnerForEntityPersistExecutor.release()); if (isDefined(filesFieldFileIds)) { @@ -1500,6 +1501,7 @@ export class WorkspaceEntityManager extends EntityManager { ) .execute() .then(() => formattedEntity as Entity | Entity[]) + // oxlint-disable-next-line @typescripttypescript/no-misused-promises .finally(() => queryRunnerForEntityPersistExecutor.release()); const formattedResult = formatResult( @@ -1648,6 +1650,7 @@ export class WorkspaceEntityManager extends EntityManager { ) .execute() .then(() => formattedEntity as Entity) + // oxlint-disable-next-line @typescripttypescript/no-misused-promises .finally(() => queryRunnerForEntityPersistExecutor.release()); const formattedResult = formatResult( @@ -1797,6 +1800,7 @@ export class WorkspaceEntityManager extends EntityManager { ) .execute() .then(() => formattedEntity as Entity) + // oxlint-disable-next-line @typescripttypescript/no-misused-promises .finally(() => queryRunnerForEntityPersistExecutor.release()); const formattedResult = formatResult(