feat: auto-fallback to Clash proxy on scheduled subscription updates; refactor fallback logic and add request timeout

This commit is contained in:
wonfen
2025-04-24 22:51:45 +08:00
parent 4d37e6870c
commit 8d62c0d521
8 changed files with 123 additions and 38 deletions

View File

@@ -183,12 +183,6 @@ export const ProfileItem = (props: Props) => {
setAnchorEl(null);
setLoadingCache((cache) => ({ ...cache, [itemData.uid]: true }));
// 存储原始设置以便回退后恢复
const originalOptions = {
with_proxy: itemData.option?.with_proxy,
self_proxy: itemData.option?.self_proxy
};
// 根据类型设置初始更新选项
const option: Partial<IProfileOption> = {};
if (type === 0) {
@@ -205,31 +199,15 @@ export const ProfileItem = (props: Props) => {
}
try {
// 尝试正常更新
// 调用后端更新(后端会自动处理回退逻辑)
await updateProfile(itemData.uid, option);
// 更新成功,刷新列表
Notice.success(t("Update subscription successfully"));
mutate("getProfiles");
} catch (err: any) {
// 更新失败,尝试使用自身代理
const errmsg = err?.message || err.toString();
Notice.info(t("Update failed, retrying with Clash proxy..."));
try {
await updateProfile(itemData.uid, {
with_proxy: false,
self_proxy: true
});
Notice.success(t("Update with Clash proxy successfully"));
await updateProfile(itemData.uid, originalOptions);
mutate("getProfiles");
} catch (retryErr: any) {
const retryErrmsg = retryErr?.message || retryErr.toString();
Notice.error(
`${t("Update failed even with Clash proxy")}: ${retryErrmsg.replace(/error sending request for url (\S+?): /, "")}`,
);
}
// 更新完全失败(包括后端的回退尝试)
// 不需要做处理,后端会通过事件通知系统发送错误
} finally {
setLoadingCache((cache) => ({ ...cache, [itemData.uid]: false }));
}

View File

@@ -262,6 +262,25 @@ export const ProfileViewer = forwardRef<ProfileViewerRef, Props>(
/>
)}
/>
<Controller
name="option.timeout_seconds"
control={control}
render={({ field }) => (
<TextField
{...text}
{...field}
type="number"
placeholder="60"
label={t("HTTP Request Timeout")}
InputProps={{
endAdornment: (
<InputAdornment position="end">{t("seconds")}</InputAdornment>
),
}}
/>
)}
/>
</>
)}