From be7b0788782f55da6865b5bda7b42360ef4d7890 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Tue, 2 Jun 2026 20:07:45 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20mark=20H1=20done=20=E2=80=94=20friendly?= =?UTF-8?q?=20DB-error=20layer=20is=20shipped?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verification found H1 (ADR-0019) fully implemented and tested: the friendly::translate_error chokepoint is wired on the live failure path (runtime + app + DbError::friendly_message), covers all five error categories (UNIQUE, FOREIGN KEY both sides, NOT NULL, CHECK, type-mismatch) with operation×kind×verbosity wording, the messages verbosity command, and §6 row-pinpointing via runtime-resolved facts — backed by 44 friendly unit tests + 12 full-stack friendly_enrichment integration tests. The "partial / FK-only" notes were stale. Mark requirements H1 done; fix the obsolete "diagnostic_table is always None" comment in translate.rs (pinpointing landed in 431645a). Remaining ADR-0019 scope (§9 i18n sweep, §OOS-2 advanced-SQL sanitization, §OOS-3 messages persistence) stays deferred. --- docs/requirements.md | 21 +++++++++++++++------ src/friendly/translate.rs | 24 ++++++++++++------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docs/requirements.md b/docs/requirements.md index 0bef8ab..938eae2 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -542,12 +542,21 @@ since ADR-0027.) ## Hints, help, errors -- [ ] **H1** Friendly error-rewriting layer translates SQLite - error messages into learner-friendly equivalents. - *(Progress: foreign-key constraint failures are enriched - with both inbound and outbound relationship listings (so - RESTRICT errors point at the children that still reference - this table); full SQL → English translation pending.)* +- [x] **H1** Friendly error-rewriting layer translates engine + error messages into learner-friendly equivalents (ADR-0019). + *(Done: the `friendly::translate_error` chokepoint is wired on + the live failure path (runtime + app + `DbError::friendly_message`) + and covers all five ADR-0019 §3 categories — UNIQUE, FOREIGN KEY + (parent- and child-side), NOT NULL, CHECK, and type-mismatch — + with operation×kind×verbosity catalog wording, the + `messages short|verbose` verbosity command, and §6 row-pinpointing + via runtime-resolved facts rendered through the bordered + diagnostic table. Covered by 44 `friendly` unit tests + 12 + full-stack `friendly_enrichment` integration tests. Remaining + ADR-0019 scope is deferred and separately tracked: the §9 i18n + migration sweep of all other user-facing strings, advanced-mode + SQL-error sanitization (§OOS-2), and `messages` persistence + (§OOS-3, awaits the settings ADR).)* - [ ] **H1a** Strong syntax-help in parse errors. When the user types something near-correct (e.g. `insert into T ('Oli')` — forgotten `values`; or `update T set x=1` — missing WHERE), diff --git a/src/friendly/translate.rs b/src/friendly/translate.rs index b00af9c..cbbe194 100644 --- a/src/friendly/translate.rs +++ b/src/friendly/translate.rs @@ -16,18 +16,18 @@ //! //! ADR-0019 §6 calls for re-querying the database after a //! constraint failure to surface the offending row(s) through -//! ADR-0017's bordered diagnostic-table renderer. That layer -//! is plumbed structurally — [`FriendlyError::diagnostic_table`] -//! exists for it — but the actual re-query implementation is a -//! separate commit alongside its runtime-side wiring (the -//! translator needs the user's attempted values, which arrive -//! through [`TranslateContext`] populated at the runtime -//! callsite). -//! -//! For now, [`FriendlyError::diagnostic_table`] is always -//! `None` and the wording carries the full burden. Adding the -//! diagnostic table later is purely additive: the translator's -//! catalog keys and the renderer don't change. +//! ADR-0017's bordered diagnostic-table renderer. This is +//! **implemented** (commit `431645a`): the *runtime* resolves the +//! schema-dependent facts — table/column, parent/child tables, the +//! attempted value, and any pinpointed rows — into a +//! [`FailureContext`], which [`TranslateContext::from_facts`] feeds +//! into the translator. When those facts carry a pinpoint, +//! [`FriendlyError::diagnostic_table`] is populated and the renderer +//! appends the bordered table; when they don't (no live DB handle, +//! re-query failed, or a fallback callsite), it stays `None` and the +//! catalog wording carries the full burden. The translator itself +//! never touches the database — it only renders the facts it is +//! handed — so the two layers stay cleanly separable. use crate::db::{DbError, SqliteErrorKind}; use crate::dsl::Type;