diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordsFieldVisibleGqlFields.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordsFieldVisibleGqlFields.ts index 7066c72bc0..97f5fc4173 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordsFieldVisibleGqlFields.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordsFieldVisibleGqlFields.ts @@ -37,10 +37,12 @@ export const useRecordsFieldVisibleGqlFields = ({ const allDepthOneGqlFields = generateDepthRecordGqlFieldsFromFields({ objectMetadataItems, - fields: visibleRecordFields.map( - (field) => - fieldMetadataItemByFieldMetadataItemId[field.fieldMetadataItemId], - ), + fields: visibleRecordFields + .map( + (field) => + fieldMetadataItemByFieldMetadataItemId[field.fieldMetadataItemId], + ) + .filter(isDefined), depth: 1, isFilesFieldMigrated, }); diff --git a/packages/twenty-server/src/utils/__test__/get-domain-name-by-email.spec.ts b/packages/twenty-server/src/utils/__test__/get-domain-name-by-email.spec.ts index afc7424d79..e28b2ccb9d 100644 --- a/packages/twenty-server/src/utils/__test__/get-domain-name-by-email.spec.ts +++ b/packages/twenty-server/src/utils/__test__/get-domain-name-by-email.spec.ts @@ -1,3 +1,7 @@ +import { + ErrorCode, + UserInputError, +} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { getDomainNameByEmail } from 'src/utils/get-domain-name-by-email'; describe('getDomainNameByEmail', () => { @@ -5,24 +9,67 @@ describe('getDomainNameByEmail', () => { expect(getDomainNameByEmail('user@example.com')).toBe('example.com'); }); - it('should throw an error if email is empty', () => { - expect(() => getDomainNameByEmail('')).toThrow('Email is required'); + it('should throw a UserInputError if email is empty', () => { + expect(() => getDomainNameByEmail('')).toThrow(UserInputError); + expect(() => getDomainNameByEmail('')).toThrow( + 'Email is required. Please provide a valid email address.', + ); + + try { + getDomainNameByEmail(''); + } catch (error) { + expect(error).toBeInstanceOf(UserInputError); + expect(error.extensions.code).toBe(ErrorCode.BAD_USER_INPUT); + expect(error.extensions.userFriendlyMessage.message).toContain( + 'Email is required. Please provide a valid email address.', + ); + } }); - it('should throw an error if email does not contain "@"', () => { + it('should throw a UserInputError if email does not contain "@"', () => { expect(() => getDomainNameByEmail('userexample.com')).toThrow( - 'Invalid email format', + UserInputError, ); + + try { + getDomainNameByEmail('userexample.com'); + } catch (error) { + expect(error).toBeInstanceOf(UserInputError); + expect(error.extensions.code).toBe(ErrorCode.BAD_USER_INPUT); + expect(error.extensions.userFriendlyMessage.message).toContain( + 'The provided email address is not valid. Please use a standard email format (e.g., user@example.com).', + ); + } }); - it('should throw an error if email has more than one "@"', () => { + it('should throw a UserInputError if email has more than one "@"', () => { expect(() => getDomainNameByEmail('user@example@com')).toThrow( - 'Invalid email format', + UserInputError, ); + + try { + getDomainNameByEmail('user@example@com'); + } catch (error) { + expect(error).toBeInstanceOf(UserInputError); + expect(error.extensions.code).toBe(ErrorCode.BAD_USER_INPUT); + expect(error.extensions.userFriendlyMessage.message).toContain( + 'The provided email address is not valid. Please use a standard email format (e.g., user@example.com).', + ); + } }); - it('should throw an error if domain part is empty', () => { - expect(() => getDomainNameByEmail('user@')).toThrow('Invalid email format'); + it('should throw a UserInputError if domain part is empty', () => { + expect(() => getDomainNameByEmail('user@')).toThrow(UserInputError); + + try { + getDomainNameByEmail('user@'); + } catch (error) { + expect(error).toBeInstanceOf(UserInputError); + expect(error.extensions.code).toBe(ErrorCode.BAD_USER_INPUT); + expect(error.extensions.userFriendlyMessage.message).toContain( + 'The provided email address is missing a domain. Please use a standard email format (e.g., user@example.com).', + ); + } }); // Edge cases with weird but potentially valid email formats diff --git a/packages/twenty-server/src/utils/get-domain-name-by-email.ts b/packages/twenty-server/src/utils/get-domain-name-by-email.ts index 0261fa4b1b..a4d56bf2f7 100644 --- a/packages/twenty-server/src/utils/get-domain-name-by-email.ts +++ b/packages/twenty-server/src/utils/get-domain-name-by-email.ts @@ -1,20 +1,38 @@ +import { msg } from '@lingui/core/macro'; import { isNonEmptyString } from '@sniptt/guards'; +import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; + export const getDomainNameByEmail = (email: string) => { if (!isNonEmptyString(email)) { - throw new Error('Email is required'); + throw new UserInputError( + 'Email is required. Please provide a valid email address.', + { + userFriendlyMessage: msg`Email is required. Please provide a valid email address.`, + }, + ); } const fields = email.split('@'); if (fields.length !== 2) { - throw new Error(`Invalid email format (${fields.length - 1} @) ${email}`); + throw new UserInputError( + 'The provided email address is not valid. Please use a standard email format (e.g., user@example.com).', + { + userFriendlyMessage: msg`The provided email address is not valid. Please use a standard email format (e.g., user@example.com).`, + }, + ); } const domain = fields[1]; if (!domain) { - throw new Error(`Invalid email format (no domain) ${email}`); + throw new UserInputError( + 'The provided email address is missing a domain. Please use a standard email format (e.g., user@example.com).', + { + userFriendlyMessage: msg`The provided email address is missing a domain. Please use a standard email format (e.g., user@example.com).`, + }, + ); } return domain;