From 2e7fe238ed6d79fb4ec81ebac9eee4bb25c2113e Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Wed, 3 Sep 2025 10:00:02 +0200 Subject: [PATCH] Clean step and edge errors (#14261) - add filters for both resolvers - map to gql errors Should fix https://github.com/twentyhq/core-team-issues/issues/996 --- ...rsion-edge-graphql-api-exception.filter.ts | 30 +++++++++++++++ ...rsion-step-graphql-api-exception.filter.ts | 38 +++++++++++++++++++ .../workflow-version-edge.resolver.ts | 6 ++- .../workflow-version-step.resolver.ts | 4 +- .../serverless-function.service.ts | 2 +- .../workflow-version-edge.exception.ts | 1 - .../workflow-version-step.exception.ts | 6 +-- ...workflow-version-step.workspace-service.ts | 10 ++--- 8 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-edge-graphql-api-exception.filter.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-step-graphql-api-exception.filter.ts diff --git a/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-edge-graphql-api-exception.filter.ts b/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-edge-graphql-api-exception.filter.ts new file mode 100644 index 00000000000..2f4d520047b --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-edge-graphql-api-exception.filter.ts @@ -0,0 +1,30 @@ +import { Catch, type ExceptionFilter } from '@nestjs/common'; + +import { assertUnreachable } from 'twenty-shared/utils'; + +import { NotFoundError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { + WorkflowVersionEdgeException, + WorkflowVersionEdgeExceptionCode, +} from 'src/modules/workflow/common/exceptions/workflow-version-edge.exception'; + +export const handleWorkflowVersionEdgeException = ( + exception: WorkflowVersionEdgeException, +) => { + switch (exception.code) { + case WorkflowVersionEdgeExceptionCode.NOT_FOUND: + throw new NotFoundError(exception); + default: { + assertUnreachable(exception.code); + } + } +}; + +@Catch(WorkflowVersionEdgeException) +export class WorkflowVersionEdgeGraphqlApiExceptionFilter + implements ExceptionFilter +{ + catch(exception: WorkflowVersionEdgeException) { + handleWorkflowVersionEdgeException(exception); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-step-graphql-api-exception.filter.ts b/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-step-graphql-api-exception.filter.ts new file mode 100644 index 00000000000..130b04e38d6 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/filters/workflow-version-step-graphql-api-exception.filter.ts @@ -0,0 +1,38 @@ +import { Catch, type ExceptionFilter } from '@nestjs/common'; + +import { assertUnreachable } from 'twenty-shared/utils'; + +import { + InternalServerError, + NotFoundError, + UserInputError, +} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { + WorkflowVersionStepException, + WorkflowVersionStepExceptionCode, +} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception'; + +export const handleWorkflowVersionStepException = ( + exception: WorkflowVersionStepException, +) => { + switch (exception.code) { + case WorkflowVersionStepExceptionCode.INVALID_REQUEST: + throw new UserInputError(exception); + case WorkflowVersionStepExceptionCode.NOT_FOUND: + throw new NotFoundError(exception); + case WorkflowVersionStepExceptionCode.CODE_STEP_FAILURE: + throw new InternalServerError(exception); + default: { + assertUnreachable(exception.code); + } + } +}; + +@Catch(WorkflowVersionStepException) +export class WorkflowVersionStepGraphqlApiExceptionFilter + implements ExceptionFilter +{ + catch(exception: WorkflowVersionStepException) { + handleWorkflowVersionStepException(exception); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts index ae9bc9b5881..995647238ca 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts @@ -3,6 +3,9 @@ import { Args, Mutation, Resolver } from '@nestjs/graphql'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; +import { CreateWorkflowVersionEdgeInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-edge-input.dto'; +import { WorkflowVersionStepChangesDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version-step-changes.dto'; +import { WorkflowVersionEdgeGraphqlApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-version-edge-graphql-api-exception.filter'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; @@ -10,8 +13,6 @@ import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; -import { CreateWorkflowVersionEdgeInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-edge-input.dto'; -import { WorkflowVersionStepChangesDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version-step-changes.dto'; import { WorkflowVersionEdgeWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-edge/workflow-version-edge.workspace-service'; @Resolver() @@ -24,6 +25,7 @@ import { WorkflowVersionEdgeWorkspaceService } from 'src/modules/workflow/workfl @UseFilters( PermissionsGraphqlApiExceptionFilter, PreventNestToAutoLogGraphqlErrorsFilter, + WorkflowVersionEdgeGraphqlApiExceptionFilter, ) export class WorkflowVersionEdgeResolver { constructor( diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts index 4011187f71c..4d334cbbca1 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts @@ -11,6 +11,8 @@ import { SubmitFormStepInput } from 'src/engine/core-modules/workflow/dtos/submi import { UpdateWorkflowRunStepInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-run-step-input.dto'; import { UpdateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-version-step-input.dto'; import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto'; +import { WorkflowVersionStepChangesDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version-step-changes.dto'; +import { WorkflowVersionStepGraphqlApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-version-step-graphql-api-exception.filter'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; @@ -21,7 +23,6 @@ import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-module import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service'; import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service'; -import { WorkflowVersionStepChangesDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version-step-changes.dto'; @Resolver() @UsePipes(ResolverValidationPipe) @@ -33,6 +34,7 @@ import { WorkflowVersionStepChangesDTO } from 'src/engine/core-modules/workflow/ @UseFilters( PermissionsGraphqlApiExceptionFilter, PreventNestToAutoLogGraphqlErrorsFilter, + WorkflowVersionStepGraphqlApiExceptionFilter, ) export class WorkflowVersionStepResolver { constructor( diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts index 7804732edf6..cfc72880514 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts @@ -214,7 +214,7 @@ export class ServerlessFunctionService { if (!isDefined(publishedServerlessFunction.latestVersion)) { throw new WorkflowVersionStepException( `Fail to publish serverlessFunction ${publishedServerlessFunction.id}.Received latest version ${publishedServerlessFunction.latestVersion}`, - WorkflowVersionStepExceptionCode.FAILURE, + WorkflowVersionStepExceptionCode.CODE_STEP_FAILURE, ); } diff --git a/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-edge.exception.ts b/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-edge.exception.ts index f0367a32aaf..2764ef024bf 100644 --- a/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-edge.exception.ts +++ b/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-edge.exception.ts @@ -3,6 +3,5 @@ import { CustomException } from 'src/utils/custom-exception'; export class WorkflowVersionEdgeException extends CustomException {} export enum WorkflowVersionEdgeExceptionCode { - UNKNOWN = 'UNKNOWN', NOT_FOUND = 'NOT_FOUND', } diff --git a/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-step.exception.ts b/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-step.exception.ts index 755a936705e..21b52b71668 100644 --- a/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-step.exception.ts +++ b/packages/twenty-server/src/modules/workflow/common/exceptions/workflow-version-step.exception.ts @@ -3,9 +3,7 @@ import { CustomException } from 'src/utils/custom-exception'; export class WorkflowVersionStepException extends CustomException {} export enum WorkflowVersionStepExceptionCode { - UNKNOWN = 'UNKNOWN', + INVALID_REQUEST = 'INVALID_REQUEST', NOT_FOUND = 'NOT_FOUND', - UNDEFINED = 'UNDEFINED', - FAILURE = 'FAILURE', - INVALID = 'INVALID', + CODE_STEP_FAILURE = 'CODE_STEP_FAILURE', } diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service.ts index 5912eae2b03..479f96cc081 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service.ts @@ -164,7 +164,7 @@ export class WorkflowVersionStepWorkspaceService { if (!isDefined(workflowVersion.steps)) { throw new WorkflowVersionStepException( "Can't update step from undefined steps", - WorkflowVersionStepExceptionCode.UNDEFINED, + WorkflowVersionStepExceptionCode.INVALID_REQUEST, ); } @@ -227,7 +227,7 @@ export class WorkflowVersionStepWorkspaceService { if (!isDeletingTrigger && !isDefined(workflowVersion.steps)) { throw new WorkflowVersionStepException( "Can't delete step from undefined steps", - WorkflowVersionStepExceptionCode.UNDEFINED, + WorkflowVersionStepExceptionCode.INVALID_REQUEST, ); } @@ -342,7 +342,7 @@ export class WorkflowVersionStepWorkspaceService { if (step.type !== WorkflowActionType.FORM) { throw new WorkflowVersionStepException( 'Step is not a form', - WorkflowVersionStepExceptionCode.INVALID, + WorkflowVersionStepExceptionCode.INVALID_REQUEST, { userFriendlyMessage: t`Step is not a form`, }, @@ -478,7 +478,7 @@ export class WorkflowVersionStepWorkspaceService { if (!isDefined(newServerlessFunction)) { throw new WorkflowVersionStepException( 'Fail to create Code Step', - WorkflowVersionStepExceptionCode.FAILURE, + WorkflowVersionStepExceptionCode.CODE_STEP_FAILURE, ); } @@ -671,7 +671,7 @@ export class WorkflowVersionStepWorkspaceService { default: throw new WorkflowVersionStepException( `WorkflowActionType '${type}' unknown`, - WorkflowVersionStepExceptionCode.UNKNOWN, + WorkflowVersionStepExceptionCode.INVALID_REQUEST, ); } }