Repository navigation
v1.54.1 — Error classification: a failure now says which layer broke
Fixed
-
A dropped connection, an exhausted connection pool, an unreachable host, and a TLS failure each say so.
TRANSPORT_CODESlisted seven keys, soECONNRESET,EPIPE,EHOSTUNREACH,ENETUNREACH, TLS certificate codes, PostgreSQL SQLSTATE class08and53300, and MySQL1040all carried a code, skipped the message-pattern fallback (which only runs when there is none), and landed onDatabase error (ECONNRESET): …with hints aboutdbcli schema. They now map to four new categories —CONNECTION_LOST,TOO_MANY_CONNECTIONS,EHOSTUNREACH,TLS_ERROR— each with the remedy that actually applies: retry a transient drop, inspectpg_stat_activity/Threads_connectedagainstmax_connections, check routing and VPN rather than DNS, or pointcaPath/rejectUnauthorizedat the right certificate. PostgreSQL class57(57P01/57P02/57P03) and MySQL1053/2006/2013join them: restarting the server under a running query was reported asDatabase error (57P01)with hints about confirming the statement's objects. The codeless wordings drivers use for the same event —Connection terminated unexpectedly,server closed the connection,server has gone away— are recognized too.57P03(still starting up) and08004(the server answered and refused) get their own categories rather than borrowing a message that says the opposite, and TLS is matched by code prefix because enumerating OpenSSL's verify codes would keep missing some. The envelope states each cause in its own words instead of inheriting the shared recovery code's description —CONN_HOST_NOT_FOUNDsays the name could not be resolved, which is the one thingEHOSTUNREACHrules out — and TLS failures no longer route to the credentials plan, whose second step re-runsinitfor a certificate it never asks about. The adapter-code-to-envelope-code and the connection-versus-statement tables are both exhaustiveRecords over the code union now, so a future code cannot silently inherit a generic category, and the REPL's reconnect decision reads the same table instead of its own list of codes and message substrings (#62). -
insert/update/delete/qno longer report every failure as "failed to connect". All four branched oninstanceof ConnectionErrorand applied one message key, but that class carries every adapter-level error and only four of its nine codes are transport failures — so a missing table, a syntax error, or a statement timeout all arrived asFailed to connect to database: …while the connection was fine. The wording is now chosen by code, and rendering goes through the sameformatCliErrorthe central presenter uses, so these commands print the stableCode:line and the error's hints — both previously dropped on this path — exactly asquerydoes (#61). -
A statement the server canceled is no longer reported as a connection failure. PostgreSQL
57014, MySQL3024, and MariaDB1969fell through toUNKNOWN/CONN_UNKNOWN, so the CLI answered a query that ran out of statement time with connection-troubleshooting hints and a recovery plan that opened withdbcli doctor— the one thing that was not broken. They now map to aSTATEMENT_TIMEOUTadapter code whose hints point at the query (dbcli lint,dbcli explain, re-run with an explicit--statement-timeout <ms>). The--recoveryenvelope keepsschemaVersion1 and reportsCONN_TIMEOUTwithdetails.connectionCode: "STATEMENT_TIMEOUT"; that field selects the query-oriented plan, replaces the network-flavored message with one that states the ceiling that was in force, and suppresses both thedoctor-*branches — whosebranchFork.after: 1assumed step 1 wasdoctor— and theverifystep, since nothing verifies this error except re-running the statement, which only the caller has. PostgreSQL57014isquery_canceled, not onlystatement_timeout, so apg_cancel_backend()or recovery-conflict cancel keeps the verbatimDatabase error (57014): …form rather than asserting a ceiling nobody set.