feat: typed constraint errors + onError config hook (#376)#5877
Open
edisonmoy wants to merge 2 commits into
Open
feat: typed constraint errors + onError config hook (#376)#5877edisonmoy wants to merge 2 commits into
edisonmoy wants to merge 2 commits into
Conversation
Add DrizzleConstraintError + Unique/NotNull/ForeignKey/Check subclasses (extending DrizzleQueryError, each with its own entityKind so is() works) and dialect wrap* parsers. Wire them into the pg/mysql/sqlite/singlestore core prepared queries so all drivers of each dialect get typed errors. Closes drizzle-team#376 Co-authored-by: Cursor <cursoragent@cursor.com>
Add an optional `onError(error: DrizzleQueryError)` callback to DrizzleConfig, invoked with the wrapped error before it is thrown. Threaded from drizzle() config through every driver's session into the prepared queries via a core Session.attachErrorHandler helper, so it fires consistently (including inside transactions) for pg, mysql, sqlite, singlestore and gel drivers. Refs drizzle-team#376 Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses #376 — the long-standing request for a type-safe, driver-independent way to react to query failures (unique / not-null / FK / check violations) instead of hand-parsing each driver's error codes/messages.
Two additive, fully backward-compatible changes:
1. Typed constraint errors
New classes under
drizzle-orm, all extending the existingDrizzleQueryError(each with its ownentityKind, sois()works across module/realm boundaries and the repo'srequire-entity-kindlint rule passes):DrizzleConstraintError(base) with akind: 'unique' | 'not_null' | 'foreign_key' | 'check'discriminant and best-effortconstraintName/table/columnsUniqueConstraintError,NotNullConstraintError,ForeignKeyConstraintError,CheckConstraintErrorThe original driver error is preserved on
.cause.Dialect-specific parsing (
wrapPgError/wrapMySqlError/wrapSqliteError) lives inerrors.tsand is invoked at the abstract dialect-core prepared query (pg-core/mysql-core/sqlite-core/singlestore-core). Because every concrete driver routes failures through those shared catch sites, all drivers of a dialect get typed errors with no per-driver changes. Classification is conservative — anything unrecognized falls back to a plainDrizzleQueryError. (Gel/EdgeDB keepsDrizzleQueryError; its error taxonomy isn't SQLSTATE-based.)2.
onErrorconfig hookOptional
onError?: (error: DrizzleQueryError) => voidonDrizzleConfig, called with the wrapped error before it is thrown. It is threaded fromdrizzle()through every driver's session into prepared queries via a small coreSession.attachErrorHandlerhelper, so it fires consistently across all drivers (pg, mysql, sqlite, singlestore, gel) — including inside transactions.Test plan
drizzle-orm/tests/errors.test.ts: pg/mysql/sqlite/singlestore error classification, postgres.js name aliases, composite sqlite columns, libsql message fallback,is()/instanceof/inheritance chain, fallback-to-DrizzleQueryError, and anonErrormock test.drizzle-ormunit suite passes (588 tests).tsctypecheck clean, ESLint clean (no disables,entityKind/no-instanceofsatisfied), dprint clean.Notes
DrizzleQueryError, andonErroris optional.Made with Cursor