fix(common-config): improve error handling, layer separation, and reliability across sync system

P0 Fixes:
- Enable toml `preserve_order` feature for reliable key ordering
- Extract pure detection functions to utils/commonConfigDetection.ts (fix layer inversion)
- Return structured result from preserveCodexConfigFormat to prevent data loss

P1 Fixes:
- Handle pure TOML strings in Codex config instead of silent skip
- Surface extractDiff errors in useCodexCommonConfig instead of swallowing
- Log parse errors in detectCommonConfigEnabledByContent for debugging

P2 Fixes:
- Use parsing-based assertions in Rust TOML ordering tests
- Add schema warning when Codex config field is wrong type
- Add depth/node limits to isSubset function (prevent stack overflow)
- Replace hardcoded "{}" check with adapter.hasValidContent()

P3 Fixes:
- Refactor Gemini errors to structured GeminiConfigErrorInfo format
- Add mapGeminiErrorToI18n for type-safe error-to-i18n mapping
This commit is contained in:
YoVinchen
2026-01-31 20:39:28 +08:00
parent d66f196378
commit 0ef8c127c5
10 changed files with 576 additions and 154 deletions
+1
View File
@@ -5633,6 +5633,7 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
dependencies = [
"indexmap 2.11.4",
"serde",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
+1 -1
View File
@@ -35,7 +35,7 @@ tauri-plugin-dialog = "2"
tauri-plugin-store = "2"
tauri-plugin-deep-link = "2"
dirs = "5.0"
toml = "0.8"
toml = { version = "0.8", features = ["preserve_order"] }
toml_edit = "0.22"
reqwest = { version = "0.12", features = ["rustls-tls", "json", "stream", "socks"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "time", "sync"] }
+23 -8
View File
@@ -837,17 +837,32 @@ shared_key = "shared"
assert!(result.contains("custom-model")); // custom wins
assert!(result.contains("shared_key")); // from common
// Verify ordering: custom keys appear before common-only keys
let model_pos = result.find("model").unwrap();
let custom_section_pos = result.find("custom_section").unwrap();
let shared_key_pos = result.find("shared_key").unwrap();
// With preserve_order feature enabled, verify key ordering via parsing
// instead of relying on string position (which is fragile)
let parsed: TomlValue = result.parse().expect("result should be valid TOML");
let table = parsed.as_table().expect("result should be a table");
let keys: Vec<&String> = table.keys().collect();
// Custom keys should appear before common-only keys
let model_idx = keys.iter().position(|k| *k == "model");
let custom_section_idx = keys.iter().position(|k| *k == "custom_section");
let shared_key_idx = keys.iter().position(|k| *k == "shared_key");
assert!(model_idx.is_some(), "model key should exist in result");
assert!(
model_pos < shared_key_pos,
"custom 'model' should appear before common-only 'shared_key'"
custom_section_idx.is_some(),
"custom_section key should exist in result"
);
assert!(
custom_section_pos < shared_key_pos || model_pos < shared_key_pos,
"custom keys should appear before common-only keys"
shared_key_idx.is_some(),
"shared_key key should exist in result"
);
// With preserve_order, custom keys (model, custom_section) should come before common-only keys (shared_key)
assert!(
model_idx.unwrap() < shared_key_idx.unwrap(),
"custom 'model' should appear before common-only 'shared_key' (got model_idx={:?}, shared_key_idx={:?})",
model_idx, shared_key_idx
);
}