Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code ed81aba834 chore: improve monitoring for esbuild target 'es2017' blocks top-level await in
Wrapped the raw esbuild build error in a domain-specific `LogicFunctionException` with a new `LOGIC_FUNCTION_BUILD_FAILED` exception code. Previously, esbuild build failures from user code (syntax errors, unsupported features) propagated as unhandled `Error` instances all the way to Sentry, creating noise for what is fundamentally a user input validation issue — not an application bug.

Changes:
1. **`logic-function.exception.ts`** — Added `LOGIC_FUNCTION_BUILD_FAILED` enum value and its user-friendly message ("Function build failed. Please check your code for syntax errors.")
2. **`logic-function-graphql-api-exception-handler.utils.ts`** — Added `LOGIC_FUNCTION_BUILD_FAILED` to the switch case so it's handled as a known exception type (re-thrown as-is, same pattern as `CREATE_FAILED` and `INVALID_SEED_PROJECT`)
3. **`logic-function-resource.service.ts`** — Wrapped the `await build()` call in a try/catch that converts esbuild errors into `LogicFunctionException` with the build error message preserved for debugging
2026-03-09 05:14:02 +00:00
Sonarly Claude Code a02084e445 esbuild target 'es2017' blocks top-level await in workflow code steps
https://sonarly.com/issue/4123?type=bug

Workflow activation fails when a user's code step uses top-level await because the esbuild build target is set to 'es2017', which does not support top-level await (requires es2022+).

Fix: Updated the esbuild build target from `es2017` to `es2022` in `LogicFunctionResourceService.buildInMemory()`. The `es2017` target did not support top-level `await` (introduced in ES2022), causing workflow activation to fail when users wrote code steps using this common modern JavaScript feature. The server runs on Node v24 which fully supports ES2022+, so there is no compatibility concern.

Changed file: `packages/twenty-server/src/engine/core-modules/logic-function/logic-function-resource/logic-function-resource.service.ts` — line 351: `target: 'es2017'` → `target: 'es2022'`
2026-03-09 05:14:02 +00:00
3 changed files with 22 additions and 11 deletions
@@ -343,17 +343,24 @@ export class LogicFunctionResourceService {
await fs.mkdir(dirname(builtBundleFilePath), { recursive: true });
await build({
entryPoints: [entryFilePath],
outfile: builtBundleFilePath,
platform: 'node',
format: 'esm',
target: 'es2017',
bundle: true,
sourcemap: true,
packages: 'external',
banner: NODE_ESM_CJS_BANNER,
});
try {
await build({
entryPoints: [entryFilePath],
outfile: builtBundleFilePath,
platform: 'node',
format: 'esm',
target: 'es2022',
bundle: true,
sourcemap: true,
packages: 'external',
banner: NODE_ESM_CJS_BANNER,
});
} catch (error) {
throw new LogicFunctionException(
`Build failed: ${error instanceof Error ? error.message : String(error)}`,
LogicFunctionExceptionCode.LOGIC_FUNCTION_BUILD_FAILED,
);
}
return builtBundleFilePath;
}
@@ -15,6 +15,7 @@ export enum LogicFunctionExceptionCode {
LOGIC_FUNCTION_EXECUTION_TIMEOUT = 'LOGIC_FUNCTION_EXECUTION_TIMEOUT',
LOGIC_FUNCTION_DISABLED = 'LOGIC_FUNCTION_DISABLED',
LOGIC_FUNCTION_INVALID_SEED_PROJECT = 'LOGIC_FUNCTION_INVALID_SEED_PROJECT',
LOGIC_FUNCTION_BUILD_FAILED = 'LOGIC_FUNCTION_BUILD_FAILED',
}
const getLogicFunctionExceptionUserFriendlyMessage = (
@@ -41,6 +42,8 @@ const getLogicFunctionExceptionUserFriendlyMessage = (
return msg`Logic function execution is disabled.`;
case LogicFunctionExceptionCode.LOGIC_FUNCTION_INVALID_SEED_PROJECT:
return msg`Invalid seed project configuration.`;
case LogicFunctionExceptionCode.LOGIC_FUNCTION_BUILD_FAILED:
return msg`Function build failed. Please check your code for syntax errors.`;
default:
assertUnreachable(code);
}
@@ -28,6 +28,7 @@ export const logicFunctionGraphQLApiExceptionHandler = (error: any) => {
case LogicFunctionExceptionCode.LOGIC_FUNCTION_CODE_UNCHANGED:
case LogicFunctionExceptionCode.LOGIC_FUNCTION_CREATE_FAILED:
case LogicFunctionExceptionCode.LOGIC_FUNCTION_INVALID_SEED_PROJECT:
case LogicFunctionExceptionCode.LOGIC_FUNCTION_BUILD_FAILED:
throw error;
case LogicFunctionExceptionCode.LOGIC_FUNCTION_DISABLED:
throw new ForbiddenError(error);