Fix unclear metadata validation errors (#20234)
https://github.com/user-attachments/assets/8f8f1122-3de1-4a9b-8bb4-a3c8d31e47ae --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+7
-25
@@ -95,7 +95,6 @@ export class FieldMetadataResolver {
|
||||
async createOneField(
|
||||
@Args('input') input: CreateOneFieldMetadataInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
try {
|
||||
const flatFieldMetadata = await this.fieldMetadataService.createOneField({
|
||||
@@ -105,10 +104,7 @@ export class FieldMetadataResolver {
|
||||
|
||||
return fromFlatFieldMetadataToFieldMetadataDto(flatFieldMetadata);
|
||||
} catch (error) {
|
||||
return fieldMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
return fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +113,6 @@ export class FieldMetadataResolver {
|
||||
async updateOneField(
|
||||
@Args('input') input: UpdateOneFieldMetadataInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
try {
|
||||
const flatFieldMetadata = await this.fieldMetadataService.updateOneField({
|
||||
@@ -127,10 +122,7 @@ export class FieldMetadataResolver {
|
||||
|
||||
return fromFlatFieldMetadataToFieldMetadataDto(flatFieldMetadata);
|
||||
} catch (error) {
|
||||
fieldMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +131,6 @@ export class FieldMetadataResolver {
|
||||
async deleteOneField(
|
||||
@Args('input') deleteOneFieldInput: DeleteOneFieldInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
if (!isDefined(workspaceId)) {
|
||||
throw new ForbiddenError('Could not retrieve workspace ID');
|
||||
@@ -153,10 +144,7 @@ export class FieldMetadataResolver {
|
||||
|
||||
return fromFlatFieldMetadataToFieldMetadataDto(flatFieldMetadata);
|
||||
} catch (error) {
|
||||
fieldMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +156,7 @@ export class FieldMetadataResolver {
|
||||
id: fieldMetadataId,
|
||||
objectMetadataId,
|
||||
}: Pick<FieldMetadataDTO, 'id' | 'objectMetadataId'>,
|
||||
@Context() context: { loaders: IDataloaders } & I18nContext,
|
||||
@Context() context: { loaders: IDataloaders },
|
||||
): Promise<RelationDTO | null> {
|
||||
try {
|
||||
return await context.loaders.relationLoader.load({
|
||||
@@ -177,10 +165,7 @@ export class FieldMetadataResolver {
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
} catch (error) {
|
||||
return fieldMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
return fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +177,7 @@ export class FieldMetadataResolver {
|
||||
id: fieldMetadataId,
|
||||
objectMetadataId,
|
||||
}: Pick<FieldMetadataDTO, 'id' | 'objectMetadataId'>,
|
||||
@Context() context: { loaders: IDataloaders } & I18nContext,
|
||||
@Context() context: { loaders: IDataloaders },
|
||||
): Promise<RelationDTO[] | null> {
|
||||
try {
|
||||
return await context.loaders.morphRelationLoader.load({
|
||||
@@ -201,10 +186,7 @@ export class FieldMetadataResolver {
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
} catch (error) {
|
||||
return fieldMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
return fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-14
@@ -4,31 +4,19 @@ import {
|
||||
Injectable,
|
||||
type NestInterceptor,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { type Observable, catchError } from 'rxjs';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { fieldMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/field-metadata/utils/field-metadata-graphql-api-exception-handler.util';
|
||||
|
||||
@Injectable()
|
||||
export class FieldMetadataGraphqlApiExceptionInterceptor
|
||||
implements NestInterceptor
|
||||
{
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
const gqlContext = GqlExecutionContext.create(context);
|
||||
const ctx = gqlContext.getContext();
|
||||
const locale = ctx.req?.locale ?? SOURCE_LOCALE;
|
||||
const i18n = this.i18nService.getI18nInstance(locale);
|
||||
|
||||
intercept(_context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
return next
|
||||
.handle()
|
||||
.pipe(
|
||||
catchError((err) => fieldMetadataGraphqlApiExceptionHandler(err, i18n)),
|
||||
);
|
||||
.pipe(catchError((err) => fieldMetadataGraphqlApiExceptionHandler(err)));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-7
@@ -1,4 +1,3 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
@@ -13,14 +12,11 @@ import {
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { InvalidMetadataException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { workspaceMigrationBuilderExceptionFormatter } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-exception-formatter';
|
||||
import { workspaceMigrationBuilderGraphqlApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util';
|
||||
|
||||
export const fieldMetadataGraphqlApiExceptionHandler = (
|
||||
error: Error,
|
||||
i18n: I18n,
|
||||
) => {
|
||||
export const fieldMetadataGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderException) {
|
||||
workspaceMigrationBuilderExceptionFormatter(error, i18n);
|
||||
workspaceMigrationBuilderGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
|
||||
if (error instanceof InvalidMetadataException) {
|
||||
|
||||
+3
-10
@@ -1,14 +1,12 @@
|
||||
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
|
||||
import { Context, Parent, ResolveField } from '@nestjs/graphql';
|
||||
|
||||
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
|
||||
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 { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { type I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { type IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { IndexFieldMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-field-metadata.dto';
|
||||
import { IndexMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-metadata.dto';
|
||||
@@ -23,13 +21,11 @@ import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-module
|
||||
PermissionsGraphqlApiExceptionFilter,
|
||||
)
|
||||
export class IndexMetadataResolver {
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
@ResolveField(() => [IndexFieldMetadataDTO], { nullable: false })
|
||||
async indexFieldMetadataList(
|
||||
@AuthWorkspace() workspace: WorkspaceEntity,
|
||||
@Parent() indexMetadata: IndexMetadataDTO,
|
||||
@Context() context: { loaders: IDataloaders } & I18nContext,
|
||||
@Context() context: { loaders: IDataloaders },
|
||||
): Promise<IndexFieldMetadataDTO[]> {
|
||||
try {
|
||||
const indexFieldMetadataItems =
|
||||
@@ -41,10 +37,7 @@ export class IndexMetadataResolver {
|
||||
|
||||
return indexFieldMetadataItems;
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
+2
-16
@@ -4,33 +4,19 @@ import {
|
||||
Injectable,
|
||||
type NestInterceptor,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { type Observable, catchError } from 'rxjs';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { objectMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/object-metadata/utils/object-metadata-graphql-api-exception-handler.util';
|
||||
|
||||
@Injectable()
|
||||
export class ObjectMetadataGraphqlApiExceptionInterceptor
|
||||
implements NestInterceptor
|
||||
{
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
const gqlContext = GqlExecutionContext.create(context);
|
||||
const ctx = gqlContext.getContext();
|
||||
const locale = ctx.req?.locale ?? SOURCE_LOCALE;
|
||||
const i18n = this.i18nService.getI18nInstance(locale);
|
||||
|
||||
intercept(_context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
return next
|
||||
.handle()
|
||||
.pipe(
|
||||
catchError((err) =>
|
||||
objectMetadataGraphqlApiExceptionHandler(err, i18n),
|
||||
),
|
||||
);
|
||||
.pipe(catchError((err) => objectMetadataGraphqlApiExceptionHandler(err)));
|
||||
}
|
||||
}
|
||||
|
||||
+6
-24
@@ -137,7 +137,6 @@ export class ObjectMetadataResolver {
|
||||
async createOneObject(
|
||||
@Args('input') input: CreateOneObjectInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
try {
|
||||
const flatobjectMetadata =
|
||||
@@ -148,10 +147,7 @@ export class ObjectMetadataResolver {
|
||||
|
||||
return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata);
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +156,6 @@ export class ObjectMetadataResolver {
|
||||
async deleteOneObject(
|
||||
@Args('input') deleteObjectInput: DeleteOneObjectInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
try {
|
||||
const flatobjectMetadata =
|
||||
@@ -171,10 +166,7 @@ export class ObjectMetadataResolver {
|
||||
|
||||
return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata);
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +175,6 @@ export class ObjectMetadataResolver {
|
||||
async updateOneObject(
|
||||
@Args('input') updateObjectInput: UpdateOneObjectInput,
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Context() context: I18nContext,
|
||||
) {
|
||||
try {
|
||||
const flatobjectMetadata =
|
||||
@@ -194,10 +185,7 @@ export class ObjectMetadataResolver {
|
||||
|
||||
return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata);
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,10 +206,7 @@ export class ObjectMetadataResolver {
|
||||
|
||||
return fieldMetadataItems;
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -231,7 +216,7 @@ export class ObjectMetadataResolver {
|
||||
async indexMetadataList(
|
||||
@AuthWorkspace() workspace: WorkspaceEntity,
|
||||
@Parent() objectMetadata: ObjectMetadataDTO,
|
||||
@Context() context: { loaders: IDataloaders } & I18nContext,
|
||||
@Context() context: { loaders: IDataloaders },
|
||||
): Promise<IndexMetadataDTO[]> {
|
||||
try {
|
||||
const indexMetadataItems = await context.loaders.indexMetadataLoader.load(
|
||||
@@ -243,10 +228,7 @@ export class ObjectMetadataResolver {
|
||||
|
||||
return indexMetadataItems;
|
||||
} catch (error) {
|
||||
objectMetadataGraphqlApiExceptionHandler(
|
||||
error,
|
||||
this.i18nService.getI18nInstance(context.req.locale),
|
||||
);
|
||||
objectMetadataGraphqlApiExceptionHandler(error);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
+3
-7
@@ -1,4 +1,3 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
@@ -14,14 +13,11 @@ import {
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
import { InvalidMetadataException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { workspaceMigrationBuilderExceptionFormatter } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-exception-formatter';
|
||||
import { workspaceMigrationBuilderGraphqlApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util';
|
||||
|
||||
export const objectMetadataGraphqlApiExceptionHandler = (
|
||||
error: Error,
|
||||
i18n: I18n,
|
||||
) => {
|
||||
export const objectMetadataGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderException) {
|
||||
workspaceMigrationBuilderExceptionFormatter(error, i18n);
|
||||
workspaceMigrationBuilderGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
|
||||
if (error instanceof InvalidMetadataException) {
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { type ObjectsPermissionsByRoleId } from 'twenty-shared/types';
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
@@ -755,7 +756,7 @@ describe('FieldPermissionService', () => {
|
||||
{
|
||||
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
|
||||
message: 'Role is not editable',
|
||||
userFriendlyMessage: 'This role cannot be modified.',
|
||||
userFriendlyMessage: msg`This role cannot be modified.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
+3
-7
@@ -1,4 +1,3 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
@@ -18,14 +17,11 @@ import {
|
||||
PageLayoutExceptionCode,
|
||||
} from 'src/engine/metadata-modules/page-layout/exceptions/page-layout.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { workspaceMigrationBuilderExceptionFormatter } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-exception-formatter';
|
||||
import { workspaceMigrationBuilderGraphqlApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util';
|
||||
|
||||
export const pageLayoutGraphqlApiExceptionHandler = (
|
||||
error: Error,
|
||||
i18n: I18n,
|
||||
) => {
|
||||
export const pageLayoutGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderException) {
|
||||
return workspaceMigrationBuilderExceptionFormatter(error, i18n);
|
||||
return workspaceMigrationBuilderGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
|
||||
if (error instanceof PageLayoutException) {
|
||||
|
||||
+2
-13
@@ -4,11 +4,7 @@ import {
|
||||
type ExecutionContext,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { PageLayoutTabException } from 'src/engine/metadata-modules/page-layout-tab/exceptions/page-layout-tab.exception';
|
||||
import { PageLayoutWidgetException } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
import { PageLayoutException } from 'src/engine/metadata-modules/page-layout/exceptions/page-layout.exception';
|
||||
@@ -23,21 +19,14 @@ import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager
|
||||
)
|
||||
@Injectable()
|
||||
export class PageLayoutGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
catch(
|
||||
exception:
|
||||
| PageLayoutException
|
||||
| PageLayoutTabException
|
||||
| PageLayoutWidgetException
|
||||
| WorkspaceMigrationBuilderException,
|
||||
host: ExecutionContext,
|
||||
_host: ExecutionContext,
|
||||
) {
|
||||
const gqlContext = GqlExecutionContext.create(host);
|
||||
const ctx = gqlContext.getContext();
|
||||
const userLocale = ctx.req?.locale ?? SOURCE_LOCALE;
|
||||
const i18n = this.i18nService.getI18nInstance(userLocale);
|
||||
|
||||
return pageLayoutGraphqlApiExceptionHandler(exception, i18n);
|
||||
return pageLayoutGraphqlApiExceptionHandler(exception);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewFieldExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-field/exceptions/view-field.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewFieldRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewFilterGroupExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-filter-group/exceptions/view-filter-group.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewFilterGroupRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewFilterExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-filter/exceptions/view-filter.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewFilterRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewGroupExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewGroupRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+2
-7
@@ -1,5 +1,3 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import {
|
||||
ViewGroupException,
|
||||
@@ -7,10 +5,7 @@ import {
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { viewGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/view/utils/view-graphql-api-exception-handler.util';
|
||||
|
||||
export const viewGroupGraphqlApiExceptionHandler = (
|
||||
error: Error,
|
||||
i18n: I18n,
|
||||
) => {
|
||||
export const viewGroupGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof ViewGroupException) {
|
||||
if (
|
||||
error.code ===
|
||||
@@ -22,5 +17,5 @@ export const viewGroupGraphqlApiExceptionHandler = (
|
||||
}
|
||||
}
|
||||
|
||||
return viewGraphqlApiExceptionHandler(error, i18n);
|
||||
return viewGraphqlApiExceptionHandler(error);
|
||||
};
|
||||
|
||||
+2
-13
@@ -4,11 +4,7 @@ import {
|
||||
type ExecutionContext,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { ViewGroupException } from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { viewGroupGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/view-group/utils/view-group-graphql-api-exception-handler.util';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
@@ -16,17 +12,10 @@ import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager
|
||||
@Catch(ViewGroupException, WorkspaceMigrationBuilderException)
|
||||
@Injectable()
|
||||
export class ViewGroupGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
catch(
|
||||
exception: ViewGroupException | WorkspaceMigrationBuilderException,
|
||||
host: ExecutionContext,
|
||||
_host: ExecutionContext,
|
||||
) {
|
||||
const gqlContext = GqlExecutionContext.create(host);
|
||||
const ctx = gqlContext.getContext();
|
||||
const userLocale = ctx.req?.locale ?? SOURCE_LOCALE;
|
||||
const i18n = this.i18nService.getI18nInstance(userLocale);
|
||||
|
||||
return viewGroupGraphqlApiExceptionHandler(exception, i18n);
|
||||
return viewGroupGraphqlApiExceptionHandler(exception);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewSortExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-sort/exceptions/view-sort.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewSortRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
-14
@@ -16,7 +16,7 @@ import {
|
||||
ViewExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view/exceptions/view.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { workspaceMigrationBuilderRestApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-rest-api-exception-handler.util';
|
||||
import {
|
||||
type CustomException,
|
||||
UnknownException,
|
||||
@@ -38,19 +38,10 @@ export class ViewRestApiExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
if (exception instanceof WorkspaceMigrationBuilderException) {
|
||||
const i18n = this.i18nService.getI18nInstance(SOURCE_LOCALE);
|
||||
const { errors, summary } =
|
||||
fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError(
|
||||
exception,
|
||||
i18n,
|
||||
);
|
||||
|
||||
return response.status(400).json({
|
||||
statusCode: 400,
|
||||
error: 'METADATA_VALIDATION_ERROR',
|
||||
message: exception.message || 'Validation failed',
|
||||
errors,
|
||||
summary,
|
||||
return workspaceMigrationBuilderRestApiExceptionHandler({
|
||||
exception,
|
||||
response,
|
||||
i18n: this.i18nService.getI18nInstance(SOURCE_LOCALE),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -1,4 +1,3 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
@@ -36,11 +35,11 @@ import {
|
||||
ViewExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view/exceptions/view.exception';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { workspaceMigrationBuilderExceptionFormatter } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-exception-formatter';
|
||||
import { workspaceMigrationBuilderGraphqlApiExceptionHandler } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/workspace-migration-builder-graphql-api-exception-handler.util';
|
||||
|
||||
export const viewGraphqlApiExceptionHandler = (error: Error, i18n: I18n) => {
|
||||
export const viewGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderException) {
|
||||
return workspaceMigrationBuilderExceptionFormatter(error, i18n);
|
||||
return workspaceMigrationBuilderGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
|
||||
if (error instanceof ViewException) {
|
||||
|
||||
+2
-13
@@ -4,11 +4,7 @@ import {
|
||||
type ExecutionContext,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { ViewFieldGroupException } from 'src/engine/metadata-modules/view-field-group/exceptions/view-field-group.exception';
|
||||
import { ViewFieldException } from 'src/engine/metadata-modules/view-field/exceptions/view-field.exception';
|
||||
import { ViewFilterGroupException } from 'src/engine/metadata-modules/view-filter-group/exceptions/view-filter-group.exception';
|
||||
@@ -30,8 +26,6 @@ import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager
|
||||
)
|
||||
@Injectable()
|
||||
export class ViewGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
constructor(private readonly i18nService: I18nService) {}
|
||||
|
||||
catch(
|
||||
exception:
|
||||
| ViewException
|
||||
@@ -42,13 +36,8 @@ export class ViewGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
| ViewGroupException
|
||||
| ViewSortException
|
||||
| WorkspaceMigrationBuilderException,
|
||||
host: ExecutionContext,
|
||||
_host: ExecutionContext,
|
||||
) {
|
||||
const gqlContext = GqlExecutionContext.create(host);
|
||||
const ctx = gqlContext.getContext();
|
||||
const userLocale = ctx.req?.locale ?? SOURCE_LOCALE;
|
||||
const i18n = this.i18nService.getI18nInstance(userLocale);
|
||||
|
||||
return viewGraphqlApiExceptionHandler(exception, i18n);
|
||||
return viewGraphqlApiExceptionHandler(exception);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user