refactor(notice): make the notice table exhaustive and drop dead wire entries

D5 cleanup, frontend and backend in one commit: removes the six
config_validate::* statuses that never receive a backend send and the
set_config::ok send (enum variants, golden list 41→34, send point in
restart_clash_core), their frontend handlers, and the five i18n keys only
those handlers used. The notice table is now typed as a Record over the
generated NoticeStatus union, so a status without a frontend entry fails
to compile. The info status (sent by the silent updater for breaking
change notices, previously dropped with a console warning) now shows an
info toast — the one deliberate behavior delta.
This commit is contained in:
Tunglies
2026-10-01 04:20:26 +08:00
parent 139cc09304
commit 9e7669ff50
21 changed files with 42 additions and 180 deletions
-8
View File
@@ -24,14 +24,6 @@ These rules supplement the repository's root `AGENTS.md`.
status strings pinned by the golden tests. Status additions or changes
require frontend and backend changes in the same PR and an updated golden
list; this protects the wire contract. No exceptions.
Known dead wire entries, recorded here and intentionally kept (no tracking
issue): the `config_validate::*` statuses whose frontend handlers never
receive a backend send (`core_change`, `stdout_error`, `yaml_key_error`,
`yaml_error`, `merge_key_error`, `merge_error`), and `set_config::ok`,
sent by the backend with no frontend handler. Each variant carries its own
comment in `NoticeStatus`. Removal requires a same-PR frontend change and a
golden-list update.
5. **Preserve lock order.** The order is `config_write` before
`config_update_in_progress` before `lifecycle_lock`. Patch callers must use
the executor's guarded claim instead of independently combining these locks;
+1 -43
View File
@@ -7,7 +7,6 @@ pub use notification::frontend_wire_contract;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum NoticeStatus {
// dead send: no frontend handler
#[serde(rename = "info")]
Info,
#[serde(rename = "import_sub_url::ok")]
@@ -78,40 +77,13 @@ pub enum NoticeStatus {
MixedPortFallback,
#[serde(rename = "mixed_port::fallback_error")]
MixedPortFallbackError,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::core_change")]
ConfigValidateCoreChange,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::stdout_error")]
ConfigValidateStdoutError,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::yaml_key_error")]
ConfigValidateYamlKeyError,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::yaml_error")]
ConfigValidateYamlError,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::merge_key_error")]
ConfigValidateMergeKeyError,
// dead listener: frontend handler retained
#[allow(dead_code)]
#[serde(rename = "config_validate::merge_error")]
ConfigValidateMergeError,
// dead send: no frontend handler
#[serde(rename = "set_config::ok")]
SetConfigOk,
}
impl NoticeStatus {
/// Every variant in golden order. The wire-contract export and the golden
/// test both derive their variant list from here; expected strings stay
/// hand-written in the test so renames cannot slip through.
pub const ALL: [Self; 41] = [
pub const ALL: [Self; 34] = [
Self::Info,
Self::ImportSubUrlOk,
Self::ImportSubUrlError,
@@ -146,13 +118,6 @@ impl NoticeStatus {
Self::ConfigCoreChangeError,
Self::MixedPortFallback,
Self::MixedPortFallbackError,
Self::ConfigValidateCoreChange,
Self::ConfigValidateStdoutError,
Self::ConfigValidateYamlKeyError,
Self::ConfigValidateYamlError,
Self::ConfigValidateMergeKeyError,
Self::ConfigValidateMergeError,
Self::SetConfigOk,
];
}
@@ -198,13 +163,6 @@ mod tests {
"config_core::change_error",
"mixed_port::fallback",
"mixed_port::fallback_error",
"config_validate::core_change",
"config_validate::stdout_error",
"config_validate::yaml_key_error",
"config_validate::yaml_error",
"config_validate::merge_key_error",
"config_validate::merge_error",
"set_config::ok",
];
let actual: Vec<_> = statuses
.into_iter()
+4 -3
View File
@@ -355,11 +355,11 @@ fn sample_frontend_events(uid: &String) -> Vec<(FrontendEvent<'_>, &'static str,
),
(
FrontendEvent::NoticeMessage {
status: NoticeStatus::SetConfigOk,
status: NoticeStatus::Info,
message: Arc::from("ok"),
},
"verge://notice-message",
json!(["set_config::ok", "ok"]),
json!(["info", "ok"]),
),
(
FrontendEvent::TimerUpdated { profile_index: uid },
@@ -414,7 +414,8 @@ pub fn frontend_wire_contract() -> serde_json::Value {
.collect();
let statuses: Vec<_> = NoticeStatus::ALL
.iter()
.map(|status| serde_json::to_value(status).expect("NoticeStatus serializes"))
// A unit variant with a string rename cannot fail to serialize.
.filter_map(|status| serde_json::to_value(status).ok())
.collect();
json!({ "version": 1, "events": events, "noticeStatuses": statuses })
}
-1
View File
@@ -29,7 +29,6 @@ pub async fn restart_clash_core() {
match CoreManager::global().restart_core().await {
Ok(_) => {
announce(Refresh::Clash);
handle::Handle::notice(NoticeStatus::SetConfigOk, "ok");
}
Err(err) => {
handle::Handle::notice(NoticeStatus::SetConfigError, format!("{err:#}"));
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "فشل التحقق من تكوين الاشتراك، يرجى فحص ملف التكوين، تم التراجع عن التغييرات، تفاصيل الخطأ:",
"bootFailed": "فشل التحقق من التكوين عند الإقلاع، تم استخدام التكوين الافتراضي، يرجى فحص ملف التكوين، تفاصيل الخطأ:",
"coreChangeFailed": "فشل التحقق من التكوين عند تغيير النواة، تم استخدام التكوين الافتراضي، يرجى فحص ملف التكوين، تفاصيل الخطأ:",
"processTerminated": "تم إنهاء عملية التحقق. يرجى التحقق مما إذا كان برنامج الأمان يمنع تشغيل النواة، أو ما إذا كانت وحدة المعالجة المركزية وبيئة التشغيل في الكمبيوتر تدعمان برنامج النواة."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML syntax error, changes reverted",
"readError": "YAML read error, changes reverted",
"mappingError": "YAML mapping error, changes reverted",
"keyError": "YAML key error, changes reverted",
"generalError": "YAML error, changes reverted"
"mappingError": "YAML mapping error, changes reverted"
},
"merge": {
"syntaxError": "Merge file syntax error, changes reverted",
"mappingError": "Merge file mapping error, changes reverted",
"keyError": "Merge file key error, changes reverted",
"generalError": "Merge file error, changes reverted"
"mappingError": "Merge file mapping error, changes reverted"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Abonnement-Konfigurationsüberprüfung fehlgeschlagen. Bitte überprüfen Sie die Abonnement-Konfigurationsdatei. Die Änderungen wurden rückgängig gemacht. Fehlerdetails: ",
"bootFailed": "Start-Abonnement-Konfigurationsüberprüfung fehlgeschlagen. Die Standardkonfiguration wurde verwendet, um die App zu starten. Bitte überprüfen Sie die Abonnement-Konfigurationsdatei. Fehlerdetails: ",
"coreChangeFailed": "Konfigurationsüberprüfung beim Wechsel des Kerns fehlgeschlagen. Die Standardkonfiguration wurde verwendet, um die App zu starten. Bitte überprüfen Sie die Abonnement-Konfigurationsdatei. Fehlerdetails: ",
"processTerminated": "Der Validierungsprozess wurde beendet. Bitte prüfen Sie, ob eine Sicherheitssoftware die Ausführung des Kerns verhindert oder ob die CPU und Laufzeitumgebung Ihres Computers das Kernprogramm unterstützen."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML-Syntaxfehler. Die Änderungen wurden rückgängig gemacht.",
"readError": "YAML-Lesefehler. Die Änderungen wurden rückgängig gemacht.",
"mappingError": "YAML-Mappingfehler. Die Änderungen wurden rückgängig gemacht.",
"keyError": "YAML-Schlüsselfehler. Die Änderungen wurden rückgängig gemacht.",
"generalError": "YAML-Fehler. Die Änderungen wurden rückgängig gemacht."
"mappingError": "YAML-Mappingfehler. Die Änderungen wurden rückgängig gemacht."
},
"merge": {
"syntaxError": "Syntaxfehler in der Überdeckungsdatei. Die Änderungen wurden rückgängig gemacht.",
"mappingError": "Mappingfehler in der Überdeckungsdatei. Die Änderungen wurden rückgängig gemacht.",
"keyError": "Schlüsselfehler in der Überdeckungsdatei. Die Änderungen wurden rückgängig gemacht.",
"generalError": "Fehler in der Überdeckungsdatei. Die Änderungen wurden rückgängig gemacht."
"mappingError": "Mappingfehler in der Überdeckungsdatei. Die Änderungen wurden rückgängig gemacht."
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Subscription configuration validation failed. Please check the subscription configuration file; modifications have been rolled back.",
"bootFailed": "Boot subscription configuration validation failed. Started with the default configuration; please check the subscription configuration file.",
"coreChangeFailed": "Configuration validation failed when switching the kernel. Started with the default configuration; please check the subscription configuration file.",
"processTerminated": "The validation process was terminated. Please check whether security software is preventing the core from running, or whether your computer's CPU and runtime environment support the core executable."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML syntax error, changes reverted",
"readError": "YAML read error, changes reverted",
"mappingError": "YAML mapping error, changes reverted",
"keyError": "YAML key error, changes reverted",
"generalError": "YAML error, changes reverted"
"mappingError": "YAML mapping error, changes reverted"
},
"merge": {
"syntaxError": "Merge file syntax error, changes reverted",
"mappingError": "Merge file mapping error, changes reverted",
"keyError": "Merge file key error, changes reverted",
"generalError": "Merge file error, changes reverted"
"mappingError": "Merge file mapping error, changes reverted"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Error de validación de la configuración de la suscripción. Compruebe el archivo de configuración de la suscripción. Los cambios se han deshecho. Detalles del error: ",
"bootFailed": "Error de validación de la configuración de la suscripción de arranque. Se ha iniciado con la configuración predeterminada. Compruebe el archivo de configuración de la suscripción. Detalles del error: ",
"coreChangeFailed": "Error de validación de la configuración al cambiar el núcleo. Se ha iniciado con la configuración predeterminada. Compruebe el archivo de configuración de la suscripción. Detalles del error: ",
"processTerminated": "El proceso de validación ha terminado. Compruebe si algún software de seguridad impide que se ejecute el núcleo o si la CPU y el entorno de ejecución del equipo son compatibles con el programa del núcleo."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "Error de sintaxis YAML. Los cambios se han deshecho",
"readError": "Error al leer el archivo YAML. Los cambios se han deshecho",
"mappingError": "Error de mapeo YAML. Los cambios se han deshecho",
"keyError": "Error de clave YAML. Los cambios se han deshecho",
"generalError": "Error YAML. Los cambios se han deshecho"
"mappingError": "Error de mapeo YAML. Los cambios se han deshecho"
},
"merge": {
"syntaxError": "Error de sintaxis en el archivo de sobrescritura. Los cambios se han deshecho",
"mappingError": "Error de mapeo en el archivo de sobrescritura. Los cambios se han deshecho",
"keyError": "Error de clave en el archivo de sobrescritura. Los cambios se han deshecho",
"generalError": "Error en el archivo de sobrescritura. Los cambios se han deshecho"
"mappingError": "Error de mapeo en el archivo de sobrescritura. Los cambios se han deshecho"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "اعتبارسنجی پیکربندی اشتراک ناموفق بود، فایل پیکربندی را بررسی کنید، تغییرات برگشت داده شد، جزئیات خطا:",
"bootFailed": "اعتبارسنجی پیکربندی هنگام راه‌اندازی ناموفق بود، پیکربندی پیش‌فرض استفاده شد، فایل پیکربندی را بررسی کنید، جزئیات خطا:",
"coreChangeFailed": "اعتبارسنجی پیکربندی هنگام تغییر هسته ناموفق بود، پیکربندی پیش‌فرض استفاده شد، فایل پیکربندی را بررسی کنید، جزئیات خطا:",
"processTerminated": "فرآیند اعتبارسنجی متوقف شد. بررسی کنید که آیا نرم‌افزار امنیتی مانع اجرای هسته شده است یا پردازنده و محیط اجرای رایانه از برنامه هسته پشتیبانی می‌کنند."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML syntax error, changes reverted",
"readError": "YAML read error, changes reverted",
"mappingError": "YAML mapping error, changes reverted",
"keyError": "YAML key error, changes reverted",
"generalError": "YAML error, changes reverted"
"mappingError": "YAML mapping error, changes reverted"
},
"merge": {
"syntaxError": "Merge file syntax error, changes reverted",
"mappingError": "Merge file mapping error, changes reverted",
"keyError": "Merge file key error, changes reverted",
"generalError": "Merge file error, changes reverted"
"mappingError": "Merge file mapping error, changes reverted"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Validasi konfigurasi langganan gagal, periksa file konfigurasi, perubahan dibatalkan, detail kesalahan:",
"bootFailed": "Validasi konfigurasi saat boot gagal, menggunakan konfigurasi default, periksa file konfigurasi, detail kesalahan:",
"coreChangeFailed": "Validasi konfigurasi saat ganti inti gagal, menggunakan konfigurasi default, periksa file konfigurasi, detail kesalahan:",
"processTerminated": "Proses validasi dihentikan. Periksa apakah perangkat lunak keamanan mencegah inti berjalan, atau apakah CPU dan lingkungan runtime komputer mendukung program inti."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML syntax error, changes reverted",
"readError": "YAML read error, changes reverted",
"mappingError": "YAML mapping error, changes reverted",
"keyError": "YAML key error, changes reverted",
"generalError": "YAML error, changes reverted"
"mappingError": "YAML mapping error, changes reverted"
},
"merge": {
"syntaxError": "Merge file syntax error, changes reverted",
"mappingError": "Merge file mapping error, changes reverted",
"keyError": "Merge file key error, changes reverted",
"generalError": "Merge file error, changes reverted"
"mappingError": "Merge file mapping error, changes reverted"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "プロファイル設定の検証に失敗しました。プロファイル設定ファイルを確認してください。変更は取り消されました。エラー詳細:",
"bootFailed": "起動時のプロファイル設定の検証に失敗しました。デフォルト設定で起動しました。プロファイル設定ファイルを確認してください。エラー詳細:",
"coreChangeFailed": "コアを切り替える際の設定検証に失敗しました。デフォルト設定で起動しました。プロファイル設定ファイルを確認してください。エラー詳細:",
"processTerminated": "検証プロセスが中断されました。セキュリティソフトウェアがコアの実行を妨げていないか、またはコンピューターの CPU/実行環境がコアプログラムに対応しているかを確認してください。"
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML構文エラーがあります。変更は取り消されました。",
"readError": "YAMLファイルの読み取りエラーがあります。変更は取り消されました。",
"mappingError": "YAMLマッピングエラーがあります。変更は取り消されました。",
"keyError": "YAMLキーエラーがあります。変更は取り消されました。",
"generalError": "YAMLエラーがあります。変更は取り消されました。"
"mappingError": "YAMLマッピングエラーがあります。変更は取り消されました。"
},
"merge": {
"syntaxError": "上書きファイルの構文エラーがあります。変更は取り消されました。",
"mappingError": "上書きファイルのマッピングエラーがあります。変更は取り消されました。",
"keyError": "上書きファイルのキーエラーがあります。変更は取り消されました。",
"generalError": "上書きファイルにエラーがあります。変更は取り消されました。"
"mappingError": "上書きファイルのマッピングエラーがあります。変更は取り消されました。"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "설정 검증 실패",
"bootFailed": "부팅 설정 검증 실패",
"coreChangeFailed": "코어 변경 설정 검증 실패",
"processTerminated": "설정 검증 프로세스가 종료되었습니다. 보안 소프트웨어가 코어 실행을 차단하고 있는지 또는 컴퓨터의 CPU 및 실행 환경이 코어 프로그램을 지원하는지 확인하세요."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML 구문 오류",
"readError": "YAML 읽기 오류",
"mappingError": "YAML 매핑 오류",
"keyError": "YAML 키 오류",
"generalError": "YAML 오류"
"mappingError": "YAML 매핑 오류"
},
"merge": {
"syntaxError": "병합 파일 구문 오류",
"mappingError": "병합 파일 매핑 오류",
"keyError": "병합 파일 키 오류",
"generalError": "병합 파일 오류"
"mappingError": "병합 파일 매핑 오류"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Ошибка проверки конфигурации подписки, проверьте файл конфигурации, изменения отменены, ошибка:",
"bootFailed": "Ошибка проверки конфигурации при запуске, используется конфигурация по умолчанию, проверьте файл конфигурации, ошибка:",
"coreChangeFailed": "Ошибка проверки конфигурации при смене ядра, используется конфигурация по умолчанию, проверьте файл конфигурации, ошибка:",
"processTerminated": "Процесс проверки был прерван. Проверьте, не блокирует ли защитное ПО запуск ядра и поддерживают ли процессор и среда выполнения компьютера программу ядра."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "Ошибка синтаксиса YAML, откат изменений",
"readError": "Ошибка чтения YAML, откат изменений",
"mappingError": "Ошибка сопоставления YAML, откат изменений",
"keyError": "Ошибка ключа YAML, откат изменений",
"generalError": "Ошибка YAML, откат изменений"
"mappingError": "Ошибка сопоставления YAML, откат изменений"
},
"merge": {
"syntaxError": "Ошибка синтаксиса Merge File, откат изменений",
"mappingError": "Ошибка сопоставления в Merge File, откат изменений",
"keyError": "Ошибка ключа в Merge File, откат изменений",
"generalError": "Ошибка Merge File, откат изменений"
"mappingError": "Ошибка сопоставления в Merge File, откат изменений"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Abonelik yapılandırması doğrulaması başarısız oldu. Lütfen abonelik yapılandırma dosyasını kontrol edin; değişiklikler geri alındı.",
"bootFailed": "Başlangıç abonelik yapılandırması doğrulaması başarısız oldu. Varsayılan yapılandırma ile başlatıldı; lütfen abonelik yapılandırma dosyasını kontrol edin.",
"coreChangeFailed": "Çekirdek değiştirilirken yapılandırma doğrulaması başarısız oldu. Varsayılan yapılandırma ile başlatıldı; lütfen abonelik yapılandırma dosyasını kontrol edin.",
"processTerminated": "Doğrulama işlemi sonlandırıldı. Güvenlik yazılımının çekirdeğin çalışmasını engelleyip engellemediğini veya bilgisayarınızın CPU ve çalışma ortamının çekirdek programını destekleyip desteklemediğini kontrol edin."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML sözdizimi hatası, değişiklikler geri alındı",
"readError": "YAML okuma hatası, değişiklikler geri alındı",
"mappingError": "YAML eşleme hatası, değişiklikler geri alındı",
"keyError": "YAML anahtar hatası, değişiklikler geri alındı",
"generalError": "YAML hatası, değişiklikler geri alındı"
"mappingError": "YAML eşleme hatası, değişiklikler geri alındı"
},
"merge": {
"syntaxError": "Birleştirme dosyası sözdizimi hatası, değişiklikler geri alındı",
"mappingError": "Birleştirme dosyası eşleme hatası, değişiklikler geri alındı",
"keyError": "Birleştirme dosyası anahtar hatası, değişiklikler geri alındı",
"generalError": "Birleştirme dosyası hatası, değişiklikler geri alındı"
"mappingError": "Birleştirme dosyası eşleme hatası, değişiklikler geri alındı"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "Язылу көйләү тикшерүе уңышсыз, көйләү файлын тикшерегез, үзгәрешләр кире кайтарылды, хата:",
"bootFailed": "Йөкләү вакытында көйләү тикшерүе уңышсыз, стандарт көйләү кулланылды, көйләү файлын тикшерегез, хата:",
"coreChangeFailed": "Ядро алыштырганда көйләү тикшерүе уңышсыз, стандарт көйләү кулланылды, көйләү файлын тикшерегез, хата:",
"processTerminated": "Тикшерү процессы туктатылды. Иминлек программасы үзәкнең эшләвенә комачауламыймы һәм компьютерның CPU/эш мохите үзәк программасын эшләтә аламы икәнен тикшерегез."
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML syntax error, changes reverted",
"readError": "YAML read error, changes reverted",
"mappingError": "YAML mapping error, changes reverted",
"keyError": "YAML key error, changes reverted",
"generalError": "YAML error, changes reverted"
"mappingError": "YAML mapping error, changes reverted"
},
"merge": {
"syntaxError": "Merge file syntax error, changes reverted",
"mappingError": "Merge file mapping error, changes reverted",
"keyError": "Merge file key error, changes reverted",
"generalError": "Merge file error, changes reverted"
"mappingError": "Merge file mapping error, changes reverted"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "订阅配置校验失败,请检查订阅配置文件,变更已撤销,错误详情:",
"bootFailed": "启动订阅配置校验失败,已使用默认配置启动;请检查订阅配置文件,错误详情:",
"coreChangeFailed": "切换内核时配置校验失败,已使用默认配置启动;请检查订阅配置文件,错误详情:",
"processTerminated": "验证进程被终止,请检查是否有安全软件阻止了内核运行,或电脑 CPU/运行环境是否支持该内核程序。"
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML 语法错误,变更已撤销",
"readError": "YAML 读取错误,变更已撤销",
"mappingError": "YAML 映射错误,变更已撤销",
"keyError": "YAML 键错误,变更已撤销",
"generalError": "YAML 错误,变更已撤销"
"mappingError": "YAML 映射错误,变更已撤销"
},
"merge": {
"syntaxError": "覆写文件语法错误,变更已撤销",
"mappingError": "覆写文件映射错误,变更已撤销",
"keyError": "覆写文件键错误,变更已撤销",
"generalError": "覆写文件错误,变更已撤销"
"mappingError": "覆写文件映射错误,变更已撤销"
}
}
},
+2 -7
View File
@@ -108,7 +108,6 @@
"config": {
"failed": "訂閱配置校驗失敗,請檢查訂閱配置文件,變更已撤銷,錯誤詳情:",
"bootFailed": "啟動訂閱配置校驗失敗,已使用預設配置啟動;請檢查訂閱配置文件,錯誤詳情:",
"coreChangeFailed": "切換內核時配置校驗失敗,已使用預設配置啟動;請檢查訂閱配置文件,錯誤詳情:",
"processTerminated": "驗證程序被終止,請檢查是否有安全軟體阻止了內核執行,或電腦的 CPU/執行環境是否支援該內核程式。"
},
"script": {
@@ -120,15 +119,11 @@
"yaml": {
"syntaxError": "YAML 語法錯誤,變更已撤銷",
"readError": "YAML 讀取錯誤,變更已撤銷",
"mappingError": "YAML 映射錯誤,變更已撤銷",
"keyError": "YAML 鍵錯誤,變更已撤銷",
"generalError": "YAML 錯誤,變更已撤銷"
"mappingError": "YAML 映射錯誤,變更已撤銷"
},
"merge": {
"syntaxError": "覆寫檔案語法錯誤,變更已撤銷",
"mappingError": "覆寫檔案映射錯誤,變更已撤銷",
"keyError": "覆寫檔案鍵錯誤,變更已撤銷",
"generalError": "覆寫檔案錯誤,變更已撤銷"
"mappingError": "覆寫檔案映射錯誤,變更已撤銷"
}
}
},
-7
View File
@@ -39,13 +39,6 @@ export type NoticeStatus =
| 'config_core::change_error'
| 'mixed_port::fallback'
| 'mixed_port::fallback_error'
| 'config_validate::core_change'
| 'config_validate::stdout_error'
| 'config_validate::yaml_key_error'
| 'config_validate::yaml_error'
| 'config_validate::merge_key_error'
| 'config_validate::merge_error'
| 'set_config::ok'
/** Event name → payload type for every backend-emitted event. */
export interface VergeEventPayloads {
+11 -17
View File
@@ -8,6 +8,7 @@ import {
takeServiceOwnerNotice,
takeServiceRepairNotice,
} from '@/services/cmds'
import type { NoticeStatus } from '@/services/contract'
import { hideNotice, showNotice } from '@/services/notice-service'
import { requestService } from '@/services/service-request'
@@ -26,13 +27,21 @@ export const forgetShownStartupError = () => {
settledStartupErrorRead = ++startupErrorReads
}
/**
* Exhaustive notice table: one entry per contract `NoticeStatus`. The Record
* type makes a backend status without a frontend entry a compile error (and
* contract regeneration keeps the union in sync).
*/
export const handleNoticeMessage = (
status: string,
msg: string,
t: TranslateFunction,
navigate: NavigateFunction,
) => {
const handlers: Record<string, () => void> = {
const handlers: Record<NoticeStatus, () => void> = {
info: () => {
if (msg) showNotice.info(msg)
},
'import_sub_url::ok': () => {
// 空 msg 传入,我们不希望导致 后端-前端-后端 死循环,这里只做提醒。
// 未来细分事件通知时,可以考虑传入订阅 ID 或其他标识符
@@ -190,17 +199,10 @@ export const handleNoticeMessage = (
update_failed: () => showNotice.error(msg),
'config_validate::boot_error': () =>
showNotice.error('shared.feedback.validation.config.bootFailed', msg),
'config_validate::core_change': () =>
showNotice.error(
'shared.feedback.validation.config.coreChangeFailed',
msg,
),
'config_validate::error': () =>
showNotice.error('shared.feedback.validation.config.failed', msg),
'config_validate::process_terminated': () =>
showNotice.error('shared.feedback.validation.config.processTerminated'),
'config_validate::stdout_error': () =>
showNotice.error('shared.feedback.validation.config.failed', msg),
'config_validate::script_error': () =>
showNotice.error('shared.feedback.validation.script.fileError', msg),
'config_validate::script_syntax_error': () =>
@@ -215,18 +217,10 @@ export const handleNoticeMessage = (
showNotice.error('shared.feedback.validation.yaml.readError', msg),
'config_validate::yaml_mapping_error': () =>
showNotice.error('shared.feedback.validation.yaml.mappingError', msg),
'config_validate::yaml_key_error': () =>
showNotice.error('shared.feedback.validation.yaml.keyError', msg),
'config_validate::yaml_error': () =>
showNotice.error('shared.feedback.validation.yaml.generalError', msg),
'config_validate::merge_syntax_error': () =>
showNotice.error('shared.feedback.validation.merge.syntaxError', msg),
'config_validate::merge_mapping_error': () =>
showNotice.error('shared.feedback.validation.merge.mappingError', msg),
'config_validate::merge_key_error': () =>
showNotice.error('shared.feedback.validation.merge.keyError', msg),
'config_validate::merge_error': () =>
showNotice.error('shared.feedback.validation.merge.generalError', msg),
'config_core::change_success': () =>
showNotice.success(
'settings.feedback.notifications.clash.changeSuccess',
@@ -251,7 +245,7 @@ export const handleNoticeMessage = (
),
}
const handler = handlers[status]
const handler = handlers[status as NoticeStatus]
if (handler) {
handler()
} else {
-5
View File
@@ -900,7 +900,6 @@ export const translationKeys = [
'shared.feedback.notifications.common.refreshFailed',
'shared.feedback.validation.config.failed',
'shared.feedback.validation.config.bootFailed',
'shared.feedback.validation.config.coreChangeFailed',
'shared.feedback.validation.config.processTerminated',
'shared.feedback.validation.script.syntaxError',
'shared.feedback.validation.script.missingMain',
@@ -909,12 +908,8 @@ export const translationKeys = [
'shared.feedback.validation.yaml.syntaxError',
'shared.feedback.validation.yaml.readError',
'shared.feedback.validation.yaml.mappingError',
'shared.feedback.validation.yaml.keyError',
'shared.feedback.validation.yaml.generalError',
'shared.feedback.validation.merge.syntaxError',
'shared.feedback.validation.merge.mappingError',
'shared.feedback.validation.merge.keyError',
'shared.feedback.validation.merge.generalError',
'shared.filters.logLevels.all',
'shared.filters.logLevels.debug',
'shared.filters.logLevels.info',
-5
View File
@@ -1464,13 +1464,10 @@ export interface TranslationResources {
validation: {
config: {
bootFailed: string
coreChangeFailed: string
failed: string
processTerminated: string
}
merge: {
generalError: string
keyError: string
mappingError: string
syntaxError: string
}
@@ -1481,8 +1478,6 @@ export interface TranslationResources {
syntaxError: string
}
yaml: {
generalError: string
keyError: string
mappingError: string
readError: string
syntaxError: string