Exception → PostgreSQL SQLSTATE classification for the pgwire layer.
Postgres clients branch on SQLSTATE codes: Odoo retries 40001 (serialization_failure) and 40P01 (deadlock_detected); ORMs map 23505 to 'unique violation', 23502 to 'not-null violation', 22P02 to 'invalid input syntax', etc. Returning XX000 or 42000 for everything makes these signals invisible.
Lookup order when classifying a Throwable:
:sqlstate (explicit override wins).:datahike/canceled → "57014" (query_canceled). Datahike
core stays postgres-agnostic — it raises a plain
{:datahike/canceled true} ex-info; this layer translates to the
wire code at the boundary.:error keyword, via dh-error->sqlstate.:error).Canonical code list: postgres/src/backend/utils/errcodes.txt.
Exception → PostgreSQL SQLSTATE classification for the pgwire layer.
Postgres clients branch on SQLSTATE codes: Odoo retries 40001
(serialization_failure) and 40P01 (deadlock_detected); ORMs map 23505
to 'unique violation', 23502 to 'not-null violation', 22P02 to 'invalid
input syntax', etc. Returning XX000 or 42000 for everything makes these
signals invisible.
Lookup order when classifying a Throwable:
1. ex-data `:sqlstate` (explicit override wins).
2. ex-data `:datahike/canceled` → "57014" (query_canceled). Datahike
core stays postgres-agnostic — it raises a plain
`{:datahike/canceled true}` ex-info; this layer translates to the
wire code at the boundary.
3. ex-data `:error` keyword, via `dh-error->sqlstate`.
4. Regex pattern match on the exception message (for Datahike's
common unstructured errors that don't set `:error`).
5. Fallback: "XX000" (internal_error).
Canonical code list: postgres/src/backend/utils/errcodes.txt.(classify-exception e)Classify a Throwable to [sqlstate message fields]. Falls back to
XX000 with nil fields.
The regex pattern branch is deliberately last so that structured
:error data in ex-data always wins — a Datahike commit that throws
with both a recognizable message and explicit :error :db.unique/*
must classify as 23505 regardless of the message wording.
fields is a Java Map<String,String> of optional PG ErrorResponse
fields (n/t/c/d/D/H), or nil. The wire layer passes these to
sendError so ORMs get structured diagnostics.
Classify a Throwable to `[sqlstate message fields]`. Falls back to XX000 with nil fields. The regex pattern branch is deliberately last so that structured `:error` data in ex-data always wins — a Datahike commit that throws with both a recognizable message and explicit `:error :db.unique/*` must classify as 23505 regardless of the message wording. `fields` is a Java Map<String,String> of optional PG ErrorResponse fields (n/t/c/d/D/H), or nil. The wire layer passes these to sendError so ORMs get structured diagnostics.
(classify-message msg)Classify a bare error message string to a SQLSTATE code via regex pattern matching. Returns the code or nil when nothing matches.
LAST-RESORT fallback. The right way to set a SQLSTATE is on the ex-info at throw site: (throw (ex-info "…" {:sqlstate "23505" :table …}))
This fn exists for Datahike-internal exceptions we don't own (schema validation, value-type mismatch, CAS conflicts) — when Datahike throws without a :error key or with one we haven't mapped, the regex gets close enough that the client sees a useful SQLSTATE instead of XX000. Do not add new reliance on it from pgwire code: set :sqlstate at the throw site.
Classify a bare error message string to a SQLSTATE code via regex
pattern matching. Returns the code or nil when nothing matches.
LAST-RESORT fallback. The right way to set a SQLSTATE is on the
ex-info at throw site:
(throw (ex-info "…" {:sqlstate "23505" :table …}))
This fn exists for Datahike-internal exceptions we don't own
(schema validation, value-type mismatch, CAS conflicts) — when
Datahike throws without a :error key or with one we haven't mapped,
the regex gets close enough that the client sees a useful SQLSTATE
instead of XX000. Do not add new reliance on it from pgwire code:
set :sqlstate at the throw site.Map Datahike :error keyword (from ex-data) to PostgreSQL SQLSTATE.
The left column lists every :error key grep'd from Datahike's
source (as of 0.6.1611). When a new Datahike release adds another
one, add it here too — an unmapped key falls through to XX000
internal_error, which is what ORMs treat as 'generic failure'.
Map Datahike :error keyword (from ex-data) to PostgreSQL SQLSTATE. The left column lists every `:error` key grep'd from Datahike's source (as of 0.6.1611). When a new Datahike release adds another one, add it here too — an unmapped key falls through to XX000 internal_error, which is what ORMs treat as 'generic failure'.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |