Add relation exceptions (#12185)
Introducing a class of RelationException extending CustomException to help grouping those exception in sentries by ExceptionCode. I did not introduce a filter as these are thrown in utils that can be used in multiple places now or in the future, and filters are to be added at resolver-level.
This commit is contained in:
@ -0,0 +1,18 @@
|
|||||||
|
import { CustomException } from 'src/utils/custom-exception';
|
||||||
|
|
||||||
|
export class RelationException extends CustomException {
|
||||||
|
declare code: RelationExceptionCode;
|
||||||
|
constructor(message: string, code: RelationExceptionCode) {
|
||||||
|
super(message, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RelationExceptionCode {
|
||||||
|
RELATION_OBJECT_METADATA_NOT_FOUND = 'RELATION_OBJECT_METADATA_NOT_FOUND',
|
||||||
|
RELATION_TARGET_FIELD_METADATA_ID_NOT_FOUND = 'RELATION_TARGET_FIELD_METADATA_ID_NOT_FOUND',
|
||||||
|
RELATION_TARGET_FIELD_METADATA_NOT_FOUND = 'RELATION_TARGET_FIELD_METADATA_NOT_FOUND',
|
||||||
|
INVALID_RELATION_TYPE = 'INVALID_RELATION_TYPE',
|
||||||
|
RELATION_JOIN_COLUMN_ON_BOTH_SIDES = 'RELATION_JOIN_COLUMN_ON_BOTH_SIDES',
|
||||||
|
MISSING_RELATION_JOIN_COLUMN = 'MISSING_RELATION_JOIN_COLUMN',
|
||||||
|
MULTIPLE_JOIN_COLUMNS_FOUND = 'MULTIPLE_JOIN_COLUMNS_FOUND',
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { ForbiddenException } from '@nestjs/common';
|
||||||
|
|
||||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -29,6 +31,8 @@ export const computeRelationType = (
|
|||||||
case RelationMetadataType.MANY_TO_MANY:
|
case RelationMetadataType.MANY_TO_MANY:
|
||||||
return 'many-to-many';
|
return 'many-to-many';
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid relation type');
|
throw new ForbiddenException(
|
||||||
|
`Invalid relation type: ${relationMetadata.relationType}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,6 +4,10 @@ import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metada
|
|||||||
|
|
||||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||||
|
import {
|
||||||
|
RelationException,
|
||||||
|
RelationExceptionCode,
|
||||||
|
} from 'src/engine/twenty-orm/exceptions/relation.exception';
|
||||||
import { computeRelationType } from 'src/engine/twenty-orm/utils/compute-relation-type.util';
|
import { computeRelationType } from 'src/engine/twenty-orm/utils/compute-relation-type.util';
|
||||||
|
|
||||||
interface RelationDetails {
|
interface RelationDetails {
|
||||||
@ -31,7 +35,10 @@ export async function determineRelationDetails(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!fromObjectMetadata || !toObjectMetadata) {
|
if (!fromObjectMetadata || !toObjectMetadata) {
|
||||||
throw new Error('Object metadata not found');
|
throw new RelationException(
|
||||||
|
'Object metadata not found',
|
||||||
|
RelationExceptionCode.RELATION_OBJECT_METADATA_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const toFieldMetadata = Object.values(toObjectMetadata.fieldsById).find(
|
const toFieldMetadata = Object.values(toObjectMetadata.fieldsById).find(
|
||||||
|
|||||||
@ -4,6 +4,10 @@ import { RelationType } from 'typeorm/metadata/types/RelationTypes';
|
|||||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||||
|
|
||||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||||
|
import {
|
||||||
|
RelationException,
|
||||||
|
RelationExceptionCode,
|
||||||
|
} from 'src/engine/twenty-orm/exceptions/relation.exception';
|
||||||
import { converRelationTypeToTypeORMRelationType } from 'src/engine/twenty-orm/utils/convert-relation-type-to-typeorm-relation-type.util';
|
import { converRelationTypeToTypeORMRelationType } from 'src/engine/twenty-orm/utils/convert-relation-type-to-typeorm-relation-type.util';
|
||||||
|
|
||||||
interface RelationDetails {
|
interface RelationDetails {
|
||||||
@ -26,7 +30,10 @@ export async function determineSchemaRelationDetails(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!fieldMetadata.relationTargetObjectMetadataId) {
|
if (!fieldMetadata.relationTargetObjectMetadataId) {
|
||||||
throw new Error('Relation target object metadata ID is missing');
|
throw new RelationException(
|
||||||
|
'Relation target object metadata ID is missing',
|
||||||
|
RelationExceptionCode.RELATION_OBJECT_METADATA_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceObjectMetadata =
|
const sourceObjectMetadata =
|
||||||
@ -35,11 +42,17 @@ export async function determineSchemaRelationDetails(
|
|||||||
objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId];
|
objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId];
|
||||||
|
|
||||||
if (!sourceObjectMetadata || !targetObjectMetadata) {
|
if (!sourceObjectMetadata || !targetObjectMetadata) {
|
||||||
throw new Error(`Object metadata not found for field ${fieldMetadata.id}`);
|
throw new RelationException(
|
||||||
|
`Object metadata not found for field ${fieldMetadata.id}`,
|
||||||
|
RelationExceptionCode.RELATION_OBJECT_METADATA_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fieldMetadata.relationTargetFieldMetadataId) {
|
if (!fieldMetadata.relationTargetFieldMetadataId) {
|
||||||
throw new Error('Relation target field metadata ID is missing');
|
throw new RelationException(
|
||||||
|
'Relation target field metadata ID is missing',
|
||||||
|
RelationExceptionCode.RELATION_TARGET_FIELD_METADATA_ID_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetFieldMetadata =
|
const targetFieldMetadata =
|
||||||
|
|||||||
@ -2,6 +2,10 @@ import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfa
|
|||||||
import { WorkspaceJoinColumnsMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-join-columns-metadata-args.interface';
|
import { WorkspaceJoinColumnsMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-join-columns-metadata-args.interface';
|
||||||
import { WorkspaceRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-relation-metadata-args.interface';
|
import { WorkspaceRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-relation-metadata-args.interface';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RelationException,
|
||||||
|
RelationExceptionCode,
|
||||||
|
} from 'src/engine/twenty-orm/exceptions/relation.exception';
|
||||||
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
||||||
|
|
||||||
export const getJoinColumn = (
|
export const getJoinColumn = (
|
||||||
@ -31,8 +35,9 @@ export const getJoinColumn = (
|
|||||||
filteredJoinColumnsMetadataArgsCollection.length > 0 &&
|
filteredJoinColumnsMetadataArgsCollection.length > 0 &&
|
||||||
oppositeFilteredJoinColumnsMetadataArgsCollection.length > 0
|
oppositeFilteredJoinColumnsMetadataArgsCollection.length > 0
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new RelationException(
|
||||||
`Join column for ${relationMetadataArgs.name} relation is present on both sides`,
|
`Join column for ${relationMetadataArgs.name} relation is present on both sides`,
|
||||||
|
RelationExceptionCode.RELATION_JOIN_COLUMN_ON_BOTH_SIDES,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,8 +57,9 @@ export const getJoinColumn = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!inverseSideRelationMetadataArgs) {
|
if (!inverseSideRelationMetadataArgs) {
|
||||||
throw new Error(
|
throw new RelationException(
|
||||||
`Inverse side join column of relation ${relationMetadataArgs.name} is missing`,
|
`Inverse side join column of relation ${relationMetadataArgs.name} is missing`,
|
||||||
|
RelationExceptionCode.MISSING_RELATION_JOIN_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,16 +73,18 @@ export const getJoinColumn = (
|
|||||||
|
|
||||||
// Check if there are multiple join columns for the relation
|
// Check if there are multiple join columns for the relation
|
||||||
if (filteredJoinColumnsMetadataArgsCollection.length > 1) {
|
if (filteredJoinColumnsMetadataArgsCollection.length > 1) {
|
||||||
throw new Error(
|
throw new RelationException(
|
||||||
`Multiple join columns found for relation ${relationMetadataArgs.name}`,
|
`Multiple join columns found for relation ${relationMetadataArgs.name}`,
|
||||||
|
RelationExceptionCode.MULTIPLE_JOIN_COLUMNS_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const joinColumnsMetadataArgs = filteredJoinColumnsMetadataArgsCollection[0];
|
const joinColumnsMetadataArgs = filteredJoinColumnsMetadataArgsCollection[0];
|
||||||
|
|
||||||
if (!joinColumnsMetadataArgs) {
|
if (!joinColumnsMetadataArgs) {
|
||||||
throw new Error(
|
throw new RelationException(
|
||||||
`Join column is missing for relation ${relationMetadataArgs.name}`,
|
`Join column is missing for relation ${relationMetadataArgs.name}`,
|
||||||
|
RelationExceptionCode.MISSING_RELATION_JOIN_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user