From 26a2e021b06faf43da39232eb134c100a8852d8d Mon Sep 17 00:00:00 2001 From: th-kim0823 Date: Thu, 7 May 2026 11:29:00 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20refactor(kebab-config):?= =?UTF-8?q?=20stabilize=20ConfigInvalid.cause=20prefix=20(fb-27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace `read failed: {e}` / `parse failed: {e}` with the underscore- slugged `read_failed:` / `parse_failed:` prefixes so kebab-cli's error_classify (Task 8) and the error.v1 JSON Schema (Task 14) can treat the prefix as a stable wire contract while leaving the OS / toml-crate detail in the suffix as free-form context. Also add the symmetric `cause` non-empty assertion to the malformed-TOML test so a regression that empties `cause` on the parse path would be caught. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/kebab-config/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/kebab-config/src/lib.rs b/crates/kebab-config/src/lib.rs index ae99674..dd9b5d1 100644 --- a/crates/kebab-config/src/lib.rs +++ b/crates/kebab-config/src/lib.rs @@ -409,7 +409,7 @@ impl Config { let text = std::fs::read_to_string(path).map_err(|e| { anyhow::Error::new(ConfigInvalid { path: path.to_path_buf(), - cause: format!("read failed: {e}"), + cause: format!("read_failed: {e}"), }) })?; @@ -438,7 +438,7 @@ impl Config { let mut cfg: Self = toml::from_str(&text).map_err(|e| { anyhow::Error::new(ConfigInvalid { path: path.to_path_buf(), - cause: format!("parse failed: {e}"), + cause: format!("parse_failed: {e}"), }) })?; cfg.source_dir = path.parent().map(Path::to_path_buf); @@ -982,5 +982,6 @@ mod fb27_tests { let signal = err.downcast_ref::() .expect("malformed TOML should downcast to ConfigInvalid"); assert_eq!(signal.path, p); + assert!(!signal.cause.is_empty(), "cause should be non-empty"); } }