Exceptions
Neo4j error codes are converted to MikroORM's own exceptions, so catch blocks written against the
ORM keep working across dialects:
| Exception | Neo4j error code |
|---|---|
UniqueConstraintViolationException | Neo.ClientError.Schema.ConstraintValidationFailed |
NotNullConstraintViolationException | Neo.ClientError.Schema.PropertyExistenceError |
SyntaxErrorException | Neo.ClientError.Statement.SyntaxError |
ReadOnlyException | Neo.ClientError.Statement.AccessMode (a write on a replica) |
DeadlockException | Neo.TransientError.Transaction.DeadlockDetected |
ConnectionException | Neo.TransientError.Network.ConnectivityError |
A failing statement is logged at error level before the exception is converted and thrown, so it appears in the query log with its timing and parameters rather than only as a stack trace. See observability.
Errors raised before anything is sent
The driver refuses what it cannot honour, rather than accepting it and doing nothing. Each of these throws locally, with a message naming the alternative:
| Situation | Where it is documented |
|---|---|
isolationLevel, explicit nested propagation, pessimistic lockMode | Transactions |
A SQL raw() / sql fragment in a filter (Neo4jRawFragmentError) | Raw Cypher |
An operator with no Cypher equivalent ($hasKey and friends) | Query conditions |
$fulltext nested in $or / $not, or two of them in one query | Full-text search |
| Two collection operators on one relation | Query conditions |
| Ordering by an unexpanded to-many relation | Query conditions |
A partial (where) index, or type: 'vector' | Indexes |
A routine declaring body, language, security, or an output parameter | Stored routines |
| A write routine invoked on a read-only connection | Stored routines |
Why refuse rather than ignore?
An option that cannot be honoured must never appear to be honoured. A lockMode accepted and dropped
is a caller believing rows are locked when they are not — the dangerous half of the pair, and the
reason both entry points now throw.