This PR attemps at improving sentry grouping and filtering by - Using the exceptionCode as the fingerprint when the error is a customException. For this to work in this PR we are now throwing customExceptions instead of internalServerError deprived of their code. They will still be converted to Internal server errors when sent back as response - Filtering 4xx issues where it was missing (for emailVerification because errors were not handled, for invalid captcha and billing errors because they are httpErrors and not graphqlErrors) --------- Co-authored-by: Félix Malfait <felix@twenty.com>
87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
import { isDefined } from 'twenty-shared/utils';
|
|
|
|
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
|
import { UpdateObjectPayload } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
|
|
import {
|
|
ObjectMetadataException,
|
|
ObjectMetadataExceptionCode,
|
|
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
|
import { InvalidMetadataException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception';
|
|
import { validateMetadataNameIsNotTooLongOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name-is-not-too-long.utils';
|
|
import { validateMetadataNameIsNotTooShortOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name-is-not-too-short.utils';
|
|
import { validateMetadataNameOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name.utils';
|
|
|
|
export const validateObjectMetadataInputNamesOrThrow = <
|
|
T extends UpdateObjectPayload | CreateObjectInput,
|
|
>({
|
|
namePlural,
|
|
nameSingular,
|
|
}: T): void =>
|
|
[namePlural, nameSingular].forEach((name) => {
|
|
if (!isDefined(name)) {
|
|
return;
|
|
}
|
|
validateObjectMetadataInputNameOrThrow(name);
|
|
});
|
|
|
|
export const validateObjectMetadataInputNameOrThrow = (name: string): void => {
|
|
try {
|
|
validateMetadataNameOrThrow(name);
|
|
} catch (error) {
|
|
if (error instanceof InvalidMetadataException) {
|
|
throw new ObjectMetadataException(
|
|
error.message,
|
|
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
|
);
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export const validateObjectMetadataInputLabelsOrThrow = <
|
|
T extends CreateObjectInput,
|
|
>({
|
|
labelPlural,
|
|
labelSingular,
|
|
}: T): void =>
|
|
[labelPlural, labelSingular].forEach((label) =>
|
|
validateObjectMetadataInputLabelOrThrow(label),
|
|
);
|
|
|
|
const validateObjectMetadataInputLabelOrThrow = (name: string): void => {
|
|
const validators = [
|
|
validateMetadataNameIsNotTooShortOrThrow,
|
|
validateMetadataNameIsNotTooLongOrThrow,
|
|
];
|
|
|
|
try {
|
|
validators.forEach((validator) => validator(name.trim()));
|
|
} catch (error) {
|
|
if (error instanceof InvalidMetadataException) {
|
|
throw new ObjectMetadataException(
|
|
error.message,
|
|
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
|
);
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
type ValidateLowerCasedAndTrimmedStringAreDifferentOrThrowArgs = {
|
|
inputs: [string, string];
|
|
message: string;
|
|
};
|
|
export const validateLowerCasedAndTrimmedStringsAreDifferentOrThrow = ({
|
|
message,
|
|
inputs: [firstString, secondString],
|
|
}: ValidateLowerCasedAndTrimmedStringAreDifferentOrThrowArgs) => {
|
|
if (firstString.trim().toLowerCase() === secondString.trim().toLowerCase()) {
|
|
throw new ObjectMetadataException(
|
|
message,
|
|
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
|
);
|
|
}
|
|
};
|