DELETE person fails with misleading "Data validation error" masking a PostgreSQL deadlock
https://sonarly.com/issue/3840?type=bug A PostgreSQL deadlock during a DELETE on the person table is caught by an overly broad error handler that replaces all PostgreSQL error messages with "Data validation error.", returning a misleading HTTP 500 to the API consumer. Fix: The catch-all in `computeTwentyORMException` replaced every unhandled PostgreSQL error message with the hardcoded string `"Data validation error."`, including transient concurrency errors like deadlocks (`40P01`) and serialization failures (`40001`). This made it impossible for API consumers to distinguish a permanent validation failure from a transient error that would succeed on retry. The fix adds an explicit guard **before** the catch-all that intercepts `DEADLOCK_DETECTED` and `SERIALIZATION_FAILURE` and returns a `TwentyORMException` (instead of a `PostgresException`) with: - The real `error.message` (e.g., `"deadlock detected"`) — preserving debuggability - `TwentyORMExceptionCode.QUERY_READ_TIMEOUT` — the closest existing code for "transient, please retry" - A user-friendly message: `"We are experiencing a temporary issue with our database. Please try again later."` — consistent with the existing `QUERY_READ_TIMEOUT` pattern Using `TwentyORMException` also means the error is caught by `workspaceQueryRunnerRestApiExceptionHandler` rather than falling through to `HttpExceptionHandlerService`, which was the path that produced the misleading `InternalServerErrorException: Data validation error.`. ```typescript file=packages/twenty-server/src/engine/twenty-orm/error-handling/compute-twenty-orm-exception.ts lines=61-72 if ( errorCode === POSTGRESQL_ERROR_CODES.DEADLOCK_DETECTED || errorCode === POSTGRESQL_ERROR_CODES.SERIALIZATION_FAILURE ) { return new TwentyORMException( error.message, TwentyORMExceptionCode.QUERY_READ_TIMEOUT, { userFriendlyMessage: msg`We are experiencing a temporary issue with our database. Please try again later.`, }, ); } ```
This commit is contained in:
+13
@@ -58,6 +58,19 @@ export const computeTwentyORMException = async (
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
errorCode === POSTGRESQL_ERROR_CODES.DEADLOCK_DETECTED ||
|
||||
errorCode === POSTGRESQL_ERROR_CODES.SERIALIZATION_FAILURE
|
||||
) {
|
||||
return new TwentyORMException(
|
||||
error.message,
|
||||
TwentyORMExceptionCode.QUERY_READ_TIMEOUT,
|
||||
{
|
||||
userFriendlyMessage: msg`We are experiencing a temporary issue with our database. Please try again later.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isDefined(errorCode) &&
|
||||
Object.values(POSTGRESQL_ERROR_CODES).includes(errorCode)
|
||||
|
||||
Reference in New Issue
Block a user