Reference · Database
db.error_kind
db.error_kind(any) -> str | nullWhat it does
What kind of failure a database's error value is, in one word that is the same for
SQLite, PostgreSQL and MySQL, whose own messages differ: "unique" (a key or unique
column has the value already), "foreign_key", "not_null", "check", or
"conflict" (another transaction: the database busy, a deadlock, a serialization
failure), or "connection" (the server ended the connection, or it could not be made)
(since 0.7). Any other failure, and anything that is not a database error, is null. It
needs no effect, so it can be called from any function.
A PostgreSQL error's message ends in its SQLSTATE, in brackets: db: duplicate key value violates unique constraint "seats_pkey" (Key (k)=(1) already exists.) [23505]. The code
is read first, so the kind is found whatever language the server writes its messages in:
23505 is unique, 23503 foreign_key, 23502 not_null, 23514 check, and
40001, 40P01 and 55P03 conflict, and 57P01 to 57P03 and class 08
connection. MySQL's messages carry their code too
((1062)), and SQLite's words are always English.
Examples
db.open("app.db")db.exec("create table seats (show text, seat text, unique (show, seat))")db.exec("insert into seats values ('tonight', 'A1')")let r = db.exec("insert into seats values (?, ?)", "tonight", "A1")print(db.error_kind(r))if db.error_kind(r) == "unique" { print("Someone has just taken that seat") }uniqueSomeone has just taken that seatEdge cases
- A successful result is
null, so a check reads asdb.error_kind(r) == "unique". - An error value from somewhere else (
err("unique"), a failedread_file), a string, a number ornullisnull. - A failure the list does not cover (a missing table, bad syntax) is
null, though the value is still an error: checkis_errfor that. - A PostgreSQL server set to another language (
lc_messages = 'de_DE.UTF-8') gives the same kinds:... verletzt Unique-Constraint »seats_pkey« ... [23505]isunique. A program that compared PostgreSQL's whole message text should compare the kind, or allow for the[code]at the end.
db.open("app.db")db.exec("create table teams (id integer primary key)")db.exec("create table users (id integer primary key, email text unique not null, age integer check (age >= 0), team integer references teams(id))")print(db.error_kind(db.exec("insert into users (email) values ('a@x.io')")))print(db.error_kind(db.exec("insert into users (email) values ('a@x.io')")))print(db.error_kind(db.exec("insert into users (email) values (null)")))print(db.error_kind(db.exec("insert into users (email, age) values ('b@x.io', -1)")))print(db.error_kind(db.exec("insert into users (email, team) values ('c@x.io', 9)")))let other = db.exec("insert into nope values (1)")print(db.error_kind(other), is_err(other))print(db.error_kind(err("unique")), db.error_kind("unique"), db.error_kind(null), db.error_kind(read_file("nope")))nulluniquenot_nullcheckforeign_keynull truenull null null nullErrors
db.error_kind never fails: whatever it is given, the answer is a word or null. The
usual shape is to name the failures the user can mend and pass the rest on with ?:
db.open("app.db")db.exec("create table users (email text unique)")db.exec("insert into users values ('a@x.io')")fn signup(email: str) { let r = db.exec("insert into users values (?)", email) if db.error_kind(r) == "unique" { return err("that email is taken") } r? "welcome"}print(signup("b@x.io"), signup("a@x.io"))welcome err("that email is taken")Chaining
db.open("app.db")db.exec("create table t (n integer unique)")print([1, 1, 2] | map((n) => db.exec("insert into t values (?)", n)) | map(db.error_kind))print(db.exec("insert into t values (2)") | db.error_kind)[null, "unique", null]uniqueSee also
db.exec, db.transaction, is_err, err
Thread 0 posts
On db.error_kind(): questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.
Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo