Null filter value in not clause crashes GraphQL query parser with TypeError

https://sonarly.com/issue/13694?type=bug

The GraphQL filter parser crashes with `TypeError: Cannot convert undefined or null to object` when a `not` filter contains a field set to `null` (e.g., `{ not: { deletedAt: null } }`), because `Object.entries(null)` is called without a null guard.

Fix: Added a null guard in `GraphqlQueryFilterFieldParser.parse()` before the `Object.entries(filterValue)` call on line 72. When `filterValue` is `null` or `undefined` (e.g., from a filter like `{ not: { deletedAt: null } }`), the code now throws a `GraphqlQueryRunnerException` with `INVALID_QUERY_INPUT` code and a user-friendly message suggesting the correct syntax (`{ is: "NULL" }`).

This follows the existing patterns in the same file:
- Uses `isDefined()` from `twenty-shared/utils` (already imported)
- Uses `GraphqlQueryRunnerException` with `INVALID_QUERY_INPUT` (same pattern as the array operator check below)
- Uses `msg` from `@lingui/core/macro` for the user-friendly message (already imported)

The `INVALID_QUERY_INPUT` exception code is handled by `graphqlQueryRunnerExceptionHandler` and mapped to a `UserInputError`, which is returned as a proper GraphQL error response instead of crashing the server with an unhandled `TypeError`.

**This also resolves the monitoring noise**: the unhandled `TypeError` that was being captured by Sentry is now a properly handled `UserInputError` — a client-side input validation error that should not be reported to Sentry.
This commit is contained in:
Sonarly Claude Code
2026-03-12 13:43:12 +00:00
parent 06d4d62e90
commit 6abe8059c9
@@ -69,6 +69,17 @@ export class GraphqlQueryFilterFieldParser {
useDirectTableReference,
);
}
if (!isDefined(filterValue)) {
throw new GraphqlQueryRunnerException(
`Invalid filter value for field "${key}". Use { is: "NULL" } or { is: "NOT_NULL" } to filter on null values`,
GraphqlQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
{
userFriendlyMessage: msg`Invalid filter value for field "${key}". Use { is: "NULL" } to filter on null values`,
},
);
}
const [[operator, value]] = Object.entries(filterValue);
if (