Throw proper error on duplicate emailing domain (#22790)

Adding an emailing domain that already exists blew up with a raw
QueryFailedError and the client just saw a generic "An error occurred".
The unique index on domain is global, so the workspace-scoped existence
check never caught rows owned by another workspace.

Now the check is unscoped and throws an EmailingDomainException mapped
to CONFLICT with a proper user-facing message, in both the
createEmailingDomain mutation and the email group channel flow. Also
dropped the hardcoded catch-all snackbar on the new channel page so
server messages actually reach the user.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22790?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
neo773
2026-07-10 23:58:34 +05:30
committed by GitHub
parent cb95410a51
commit b0dc637dbd
8 changed files with 113 additions and 26 deletions
@@ -1,6 +1,11 @@
import { assertUnreachable } from 'twenty-shared/utils';
import {
EmailingDomainException,
EmailingDomainExceptionCode,
} from 'src/engine/core-modules/emailing-domain/exceptions/emailing-domain.exception';
import {
ConflictError,
ForbiddenError,
InternalServerError,
NotFoundError,
@@ -32,6 +37,16 @@ export const messageChannelGraphqlApiExceptionHandler = (error: Error) => {
}
}
if (error instanceof EmailingDomainException) {
switch (error.code) {
case EmailingDomainExceptionCode.EMAILING_DOMAIN_ALREADY_REGISTERED:
throw new ConflictError(error);
default: {
return assertUnreachable(error.code);
}
}
}
if (error instanceof ConnectedAccountException) {
switch (error.code) {
case ConnectedAccountExceptionCode.CONNECTED_ACCOUNT_OWNERSHIP_VIOLATION: