feat: ADR-0035 Amendment 1 follow-up — enrich replay errors + close message gaps
- F2-broad: replay failures now render with real schema context instead of
a contextless friendly_message(). Extract App::build_translate_context into
the shared App::translate_context_for(command, facts, verbosity); run_replay
enriches via enrich_dsl_failure + that builder. ctx_* fallbacks degrade to
neutral prose so the rare non-replay contextless callsites can't leak raw
{name} either. (SQL INSERT/UPDATE values aren't retained — ADR-0033 verbatim
— so those show real table/column + neutral "that value".)
- Gap C: SQL ALTER … ADD FOREIGN KEY on a missing child column refuses with an
SQL-appropriate "add it first", not the DSL-only --create-fk flag.
- Gap B: dropping a single-column-UNIQUE column refuses with a pointer to
`drop constraint unique from T.col` (was an opaque generic refusal).
- Gap D: 4e drop/rename CHECK-guard + 4f change-type FK-guard refusals reworded
to explain why; static_refusal reasons left as-is.
Tests: +4, 3 strengthened. 1926 pass / 0 fail / 0 skip; clippy clean.
This commit is contained in:
+24
-12
@@ -1559,20 +1559,32 @@ impl App {
|
||||
));
|
||||
}
|
||||
|
||||
/// Construct a [`TranslateContext`] by combining the
|
||||
/// runtime-supplied [`FailureContext`] (schema-resolved
|
||||
/// facts) with the operation derived from the originating
|
||||
/// [`Command`] and the App's current verbosity.
|
||||
///
|
||||
/// Schema-resolved facts win over Command-derived
|
||||
/// fallbacks where the runtime supplied them — typically
|
||||
/// the runtime knows more (the FK-relationship lookup
|
||||
/// produces `parent_table` that the Command alone can't
|
||||
/// reveal).
|
||||
/// Construct a [`TranslateContext`] from a [`Command`] + schema-
|
||||
/// resolved [`FailureContext`], using the App's current verbosity.
|
||||
/// Thin wrapper over [`Self::translate_context_for`], which is shared
|
||||
/// with the replay path (it supplies its own verbosity — ADR-0035
|
||||
/// Amendment 1, F2 follow-up).
|
||||
fn build_translate_context(
|
||||
&self,
|
||||
command: &Command,
|
||||
facts: crate::friendly::FailureContext,
|
||||
) -> crate::friendly::TranslateContext {
|
||||
Self::translate_context_for(command, facts, self.messages_verbosity)
|
||||
}
|
||||
|
||||
/// Combine the runtime-supplied [`FailureContext`] (schema-resolved
|
||||
/// facts) with the operation derived from the originating [`Command`]
|
||||
/// and an explicit `verbosity`. Schema-resolved facts win over
|
||||
/// Command-derived fallbacks where the runtime supplied them
|
||||
/// (typically the FK-relationship lookup yields a `parent_table` the
|
||||
/// Command alone can't reveal). Shared by interactive rendering and
|
||||
/// the replay failure path (ADR-0035 Amendment 1, F2 follow-up), so a
|
||||
/// replayed failing command shows real names instead of leaking
|
||||
/// `{name}` placeholders.
|
||||
pub(crate) fn translate_context_for(
|
||||
command: &Command,
|
||||
facts: crate::friendly::FailureContext,
|
||||
verbosity: crate::friendly::Verbosity,
|
||||
) -> crate::friendly::TranslateContext {
|
||||
use crate::dsl::{AlterTableAction, Command as C, IndexSelector, RelationshipSelector};
|
||||
use crate::friendly::{Operation, TranslateContext};
|
||||
@@ -1714,7 +1726,7 @@ impl App {
|
||||
// An `explain` failure (e.g. unknown table) is best
|
||||
// described by the wrapped query it failed to plan.
|
||||
C::Explain { query } => {
|
||||
return self.build_translate_context(query, facts);
|
||||
return Self::translate_context_for(query, facts, verbosity);
|
||||
}
|
||||
// App-lifecycle commands never reach this path —
|
||||
// `dispatch_input` routes them through
|
||||
@@ -1741,7 +1753,7 @@ impl App {
|
||||
value: facts.value,
|
||||
diagnostic_table: facts.diagnostic_table,
|
||||
check_rule: facts.check_rule,
|
||||
verbosity: self.messages_verbosity,
|
||||
verbosity,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user