eefae87296
## Summary Fixes #21119 — `createPerson` / `deletePerson` mutations fail with a generic `INTERNAL_SERVER_ERROR: "Data validation error."` instead of a meaningful error, blocking core CRM record management. ## Root Cause The `computeTwentyORMException` function in `twenty-orm` contains a catch-all block that matches **every known Postgres error code** via `Object.values(POSTGRESQL_ERROR_CODES).includes(errorCode)` and discards all error detail, throwing: ```ts throw new PostgresException('Data validation error.', errorCode); ``` This `PostgresException` is then converted by the GraphQL error handler into `INTERNAL_SERVER_ERROR`, masking the real constraint violation. Common mutations like `createPerson` that hit: - **`NOT_NULL_VIOLATION` (23502)** — a required field is missing - **`FOREIGN_KEY_VIOLATION` (23503)** — referenced record missing or deletion blocked by a FK - **`RESTRICT_VIOLATION` (23001)** — record deletion blocked by a referencing row ...all silently surface as the same opaque `"Data validation error."` with `INTERNAL_SERVER_ERROR`. Already handled correctly before the catch-all: - `UNIQUE_VIOLATION` → delegates to `handleDuplicateKeyError` ✅ - `INVALID_TEXT_REPRESENTATION` → `TwentyORMException(INVALID_INPUT)` ✅ - Query read timeout → `TwentyORMException(QUERY_READ_TIMEOUT)` ✅ ## Fix Add explicit handling **before** the catch-all for the four most common data-integrity constraint errors, converting them to `TwentyORMException(INVALID_INPUT)` with a clear user-facing message. The GraphQL error handler then returns `BAD_USER_INPUT` (400) instead of `INTERNAL_SERVER_ERROR` (500). ## Changes ### `packages/twenty-server/src/engine/twenty-orm/error-handling/compute-twenty-orm-exception.ts` Added specific handling for: | Postgres Code | Constant | User-facing message | |---|---|---| | `23502` | `NOT_NULL_VIOLATION` | "A required field is missing. Please provide all required values and try again." | | `23503` | `FOREIGN_KEY_VIOLATION` | "This operation references a record that does not exist or cannot be modified due to existing relationships." | | `23001` | `RESTRICT_VIOLATION` | "This record cannot be deleted because it is still referenced by other records." | ## Before / After **Before:** ```json { "data": { "createPerson": null }, "errors": [{ "message": "Data validation error.", "extensions": { "code": "INTERNAL_SERVER_ERROR" } }] } ``` **After (e.g. NOT_NULL_VIOLATION):** ```json { "data": { "createPerson": null }, "errors": [{ "message": "A required field is missing. Please provide all required values and try again.", "extensions": { "code": "BAD_USER_INPUT" } }] } ``` --------- Co-authored-by: Pantkartik <pantkartik@github.com> Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>