feat: Enhance configuration validation and error handling

- Improve config validation process with detailed logging and error tracking
- Add more robust error handling in profile updates and config patches
- Implement comprehensive config validation using clash core subprocess
This commit is contained in:
wonfen
2025-02-23 10:53:09 +08:00
parent 39973f2d24
commit 52627575ff
9 changed files with 279 additions and 42 deletions

View File

@@ -43,7 +43,7 @@ const NoticeInner = (props: InnerProps) => {
appWindow.theme().then((m) => m && setIsDark(m === "dark"));
const unlisten = appWindow.onThemeChanged((e) =>
setIsDark(e.payload === "dark")
setIsDark(e.payload === "dark"),
);
return () => {
@@ -105,25 +105,55 @@ let parent: HTMLDivElement = null!;
// @ts-ignore
export const Notice: NoticeInstance = (props) => {
const { type, message, duration } = props;
// 验证必要的参数
if (!message) {
return;
}
if (!parent) {
parent = document.createElement("div");
parent.setAttribute("id", "notice-container"); // 添加 id 便于调试
document.body.appendChild(parent);
}
const container = document.createElement("div");
parent.appendChild(container);
const root = createRoot(container);
const onUnmount = () => {
root.unmount();
if (parent) setTimeout(() => parent.removeChild(container), 500);
if (parent && container.parentNode === parent) {
setTimeout(() => {
parent.removeChild(container);
}, 500);
}
};
root.render(<NoticeInner {...props} onClose={onUnmount} />);
root.render(
<NoticeInner
type={type}
message={message}
duration={duration || 1500}
onClose={onUnmount}
/>,
);
};
(["info", "error", "success"] as const).forEach((type) => {
Notice[type] = (message, duration) => {
setTimeout(() => Notice({ type, message, duration }), 0);
Notice[type] = (message: ReactNode, duration?: number) => {
// 确保消息不为空
if (!message) {
return;
}
// 直接调用,不使用 setTimeout
Notice({
type,
message,
duration: duration || 1500, // 确保有默认值
});
};
});

View File

@@ -435,5 +435,7 @@
"Direct Mode": "直连模式",
"Enable Tray Speed": "启用托盘速率",
"Lite Mode": "轻量模式",
"Lite Mode Info": "关闭GUI界面仅保留内核运行"
"Lite Mode Info": "关闭GUI界面仅保留内核运行",
"Config Validation Failed": "订阅配置校验失败,请检查配置文件",
"Config Validation Process Terminated": "验证进程被终止"
}

View File

@@ -81,6 +81,15 @@ const Layout = () => {
case "set_config::error":
Notice.error(msg);
break;
case "config_validate::error":
Notice.error(t("Config Validation Failed"));
break;
case "config_validate::process_terminated":
Notice.error(t("Config Validation Process Terminated"));
break;
case "config_validate::stderr_error":
Notice.error(msg);
break;
default:
break;
}

View File

@@ -27,7 +27,7 @@ import { useTranslation } from "react-i18next";
import {
importProfile,
enhanceProfiles,
restartCore,
//restartCore,
getRuntimeLogs,
deleteProfile,
updateProfile,
@@ -400,8 +400,8 @@ const ProfilePage = () => {
onSave={async (prev, curr) => {
if (prev !== curr && profiles.current === item.uid) {
await onEnhance(false);
await restartCore();
Notice.success(t("Clash Core Restarted"), 1000);
// await restartCore();
// Notice.success(t("Clash Core Restarted"), 1000);
}
}}
onDelete={() => onDelete(item.uid)}