* Fix

* Fix

* Add HandleSafe
This commit is contained in:
DHR60
2026-08-14 02:20:58 +00:00
committed by GitHub
parent 9c1951178c
commit bc06a5dc21
10 changed files with 72 additions and 65 deletions
+21
View File
@@ -134,4 +134,25 @@ public static class Extension
.Replace("\r", replacement) .Replace("\r", replacement)
.Replace("\n", replacement); .Replace("\n", replacement);
} }
public static async Task<TOutput> HandleSafe<TInput, TOutput>(
this Interaction<TInput, TOutput> interaction,
TInput input,
TOutput defaultValue = default!)
{
try
{
return await interaction.Handle(input);
}
catch (UnhandledInteractionException<TInput, TOutput> ex)
{
Logging.SaveLog($"Unhandled interaction exception for input: {input}", ex);
return defaultValue;
}
catch (Exception ex)
{
Logging.SaveLog($"Exception occurred while handling interaction for input: {input}", ex);
return defaultValue;
}
}
} }
@@ -26,7 +26,7 @@ public partial class AddServer2ViewModel : MyReactiveObject, ICloseable
BrowseServerCmd = ReactiveCommand.CreateFromTask(async () => BrowseServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
var fileName = await BrowseConfigFileInteraction.Handle(RxVoid.Default); var fileName = await BrowseConfigFileInteraction.HandleSafe(RxVoid.Default);
if (fileName.IsNullOrEmpty()) if (fileName.IsNullOrEmpty())
{ {
return; return;
@@ -85,8 +85,6 @@ public partial class MainWindowViewModel : MyReactiveObject
#endregion Menu #endregion Menu
private readonly SynchronizationContext _uiContext = SynchronizationContext.Current;
#region Init #region Init
public MainWindowViewModel() public MainWindowViewModel()
@@ -302,7 +300,7 @@ public partial class MainWindowViewModel : MyReactiveObject
.ObserveOn(RxSchedulers.MainThreadScheduler) .ObserveOn(RxSchedulers.MainThreadScheduler)
.Subscribe(async blShow => .Subscribe(async blShow =>
{ {
await ShowHideWindowInteraction.Handle(blShow); await ShowHideWindowInteraction.HandleSafe(blShow);
}); });
StatusBarViewModel.SetDefaultServerRequested StatusBarViewModel.SetDefaultServerRequested
@@ -413,14 +411,25 @@ public partial class MainWindowViewModel : MyReactiveObject
private async Task RefreshServersDispatcherAsync() private async Task RefreshServersDispatcherAsync()
{ {
//await Observable.Start(async () => await RefreshServers(), RxSchedulers.MainThreadScheduler); //await Observable.Start(async () => await RefreshServers(), RxSchedulers.MainThreadScheduler);
_uiContext?.Post(_ => _ = RefreshServers(), null); await Signal.FromAsync(async () =>
{
await RefreshServers();
return RxVoid.Default;
})
.SubscribeOn(RxSchedulers.MainThreadScheduler)
.ToTask();
} }
private async Task RefreshSubscriptions() private async Task RefreshSubscriptions()
{ {
//await Observable.Start(async () => await ProfilesViewModel.RefreshSubscriptions(), RxSchedulers.MainThreadScheduler); //await Observable.Start(async () => await ProfilesViewModel.RefreshSubscriptions(), RxSchedulers.MainThreadScheduler);
await Signal.FromAsync(async () =>
_uiContext?.Post(_ => _ = ProfilesViewModel.RefreshSubscriptions(), null); {
await ProfilesViewModel.RefreshSubscriptions();
return RxVoid.Default;
})
.SubscribeOn(RxSchedulers.MainThreadScheduler)
.ToTask();
} }
#endregion Servers && Groups #endregion Servers && Groups
@@ -467,7 +476,7 @@ public partial class MainWindowViewModel : MyReactiveObject
var stringData = clipboardData; var stringData = clipboardData;
if (clipboardData == null) if (clipboardData == null)
{ {
var result = await ReadTextFromClipboardInteraction.Handle(RxVoid.Default); var result = await ReadTextFromClipboardInteraction.HandleSafe(RxVoid.Default);
if (result.IsNullOrEmpty()) if (result.IsNullOrEmpty())
{ {
NoticeManager.Instance.Enqueue(ResUI.OperationFailed); NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
@@ -490,7 +499,7 @@ public partial class MainWindowViewModel : MyReactiveObject
public async Task AddServerViaScanAsync() public async Task AddServerViaScanAsync()
{ {
var result = await ScanScreenInteraction.Handle(RxVoid.Default); var result = await ScanScreenInteraction.HandleSafe(RxVoid.Default);
await ScanScreenResult(result); await ScanScreenResult(result);
} }
@@ -502,7 +511,7 @@ public partial class MainWindowViewModel : MyReactiveObject
public async Task AddServerViaImageAsync() public async Task AddServerViaImageAsync()
{ {
var imageFileName = await BrowseImageFileInteraction.Handle(RxVoid.Default); var imageFileName = await BrowseImageFileInteraction.HandleSafe(RxVoid.Default);
await AddScanResultAsync(imageFileName); await AddScanResultAsync(imageFileName);
} }
@@ -691,10 +700,12 @@ public partial class MainWindowViewModel : MyReactiveObject
//{ //{
// await ClashProxiesViewModel.ProxiesReload(); // await ClashProxiesViewModel.ProxiesReload();
//}, RxSchedulers.MainThreadScheduler); //}, RxSchedulers.MainThreadScheduler);
RxSchedulers.MainThreadScheduler.Schedule(async () => await Signal.FromAsync(async () =>
{ {
await ClashProxiesViewModel.ProxiesReload(); await ClashProxiesViewModel.ProxiesReload();
}); return RxVoid.Default;
}).SubscribeOn(RxSchedulers.MainThreadScheduler)
.ToTask();
} }
ReloadResult(showClashUI); ReloadResult(showClashUI);
+1 -1
View File
@@ -74,7 +74,7 @@ public partial class MsgViewModel : MyReactiveObject
{ {
try try
{ {
await DispatcherShowMsgInteraction.Handle(sb.ToString()); await DispatcherShowMsgInteraction.HandleSafe(sb.ToString());
} }
catch (Exception) catch (Exception)
{ {
@@ -138,13 +138,7 @@ public partial class ProfilesSelectViewModel : MyReactiveObject, ICloseable
await RefreshServers(); await RefreshServers();
try await ProfilesFocusInteraction.HandleSafe(RxVoid.Default);
{
await ProfilesFocusInteraction.Handle(RxVoid.Default);
}
catch (UnhandledInteractionException<RxVoid, RxVoid>)
{
}
} }
private async Task ServerFilterChanged(bool c) private async Task ServerFilterChanged(bool c)
@@ -345,13 +345,7 @@ public partial class ProfilesViewModel : MyReactiveObject
await RefreshServers(); await RefreshServers();
try await ProfilesFocusInteraction.HandleSafe(RxVoid.Default);
{
await ProfilesFocusInteraction.Handle(RxVoid.Default);
}
catch (UnhandledInteractionException<RxVoid, RxVoid>)
{
}
} }
private async Task ServerFilterChanged(bool c) private async Task ServerFilterChanged(bool c)
@@ -395,13 +389,7 @@ public partial class ProfilesViewModel : MyReactiveObject
SelectedProfile = selected ?? lstModel.First(); SelectedProfile = selected ?? lstModel.First();
} }
try await DispatcherRefreshServersBizInteraction.HandleSafe(RxVoid.Default);
{
await DispatcherRefreshServersBizInteraction.Handle(RxVoid.Default);
}
catch (UnhandledInteractionException<RxVoid, RxVoid>)
{
}
} }
public async Task RefreshSubscriptions() public async Task RefreshSubscriptions()
@@ -419,7 +407,7 @@ public partial class ProfilesViewModel : MyReactiveObject
public async Task AdjustMainLvColWidth() public async Task AdjustMainLvColWidth()
{ {
await AdjustMainLvColWidthInteraction.Handle(RxVoid.Default); await AdjustMainLvColWidthInteraction.HandleSafe(RxVoid.Default);
} }
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter) private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
@@ -535,7 +523,7 @@ public partial class ProfilesViewModel : MyReactiveObject
{ {
return; return;
} }
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }
@@ -556,7 +544,7 @@ public partial class ProfilesViewModel : MyReactiveObject
private async Task RemoveDuplicateServer() private async Task RemoveDuplicateServer()
{ {
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }
@@ -631,7 +619,7 @@ public partial class ProfilesViewModel : MyReactiveObject
return; return;
} }
await ShareServerInteraction.Handle(url); await ShareServerInteraction.HandleSafe(url);
} }
private async Task GenGroupAllServer() private async Task GenGroupAllServer()
@@ -799,13 +787,13 @@ public partial class ProfilesViewModel : MyReactiveObject
} }
else else
{ {
await SetClipboardDataInteraction.Handle((string)result.Data); await SetClipboardDataInteraction.HandleSafe((string)result.Data);
NoticeManager.Instance.SendMessage(ResUI.OperationSuccess); NoticeManager.Instance.SendMessage(ResUI.OperationSuccess);
} }
} }
else else
{ {
await SaveFileDialogInteraction.Handle(item); await SaveFileDialogInteraction.HandleSafe(item);
} }
} }
@@ -854,11 +842,11 @@ public partial class ProfilesViewModel : MyReactiveObject
{ {
if (blEncode) if (blEncode)
{ {
await SetClipboardDataInteraction.Handle(Utils.Base64Encode(sb.ToString())); await SetClipboardDataInteraction.HandleSafe(Utils.Base64Encode(sb.ToString()));
} }
else else
{ {
await SetClipboardDataInteraction.Handle(sb.ToString()); await SetClipboardDataInteraction.HandleSafe(sb.ToString());
} }
NoticeManager.Instance.SendMessage(ResUI.BatchExportURLSuccessfully); NoticeManager.Instance.SendMessage(ResUI.BatchExportURLSuccessfully);
} }
@@ -881,7 +869,7 @@ public partial class ProfilesViewModel : MyReactiveObject
if (!result.IsNullOrEmpty()) if (!result.IsNullOrEmpty())
{ {
await SetClipboardDataInteraction.Handle(result); await SetClipboardDataInteraction.HandleSafe(result);
NoticeManager.Instance.SendMessage(ResUI.BatchExportURLSuccessfully); NoticeManager.Instance.SendMessage(ResUI.BatchExportURLSuccessfully);
} }
else else
@@ -925,7 +913,7 @@ public partial class ProfilesViewModel : MyReactiveObject
return; return;
} }
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }
@@ -48,7 +48,7 @@ public partial class RoutingRuleSettingViewModel : MyReactiveObject, ICloseable
}); });
ImportRulesFromFileCmd = ReactiveCommand.CreateFromTask(async () => ImportRulesFromFileCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
var fileName = await BrowseRulesFileInteraction.Handle(RxVoid.Default); var fileName = await BrowseRulesFileInteraction.HandleSafe(RxVoid.Default);
await ImportRulesFromFileAsync(fileName); await ImportRulesFromFileAsync(fileName);
}); });
ImportRulesFromClipboardCmd = ReactiveCommand.CreateFromTask(async () => ImportRulesFromClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
@@ -156,7 +156,7 @@ public partial class RoutingRuleSettingViewModel : MyReactiveObject, ICloseable
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeManager.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
} }
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }
@@ -199,7 +199,7 @@ public partial class RoutingRuleSettingViewModel : MyReactiveObject, ICloseable
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}; };
await SetClipboardDataInteraction.Handle(JsonUtils.Serialize(lst, options)); await SetClipboardDataInteraction.HandleSafe(JsonUtils.Serialize(lst, options));
} }
} }
@@ -277,7 +277,7 @@ public partial class RoutingRuleSettingViewModel : MyReactiveObject, ICloseable
var stringData = clipboardData; var stringData = clipboardData;
if (clipboardData == null) if (clipboardData == null)
{ {
var result = await ReadTextFromClipboardInteraction.Handle(RxVoid.Default); var result = await ReadTextFromClipboardInteraction.HandleSafe(RxVoid.Default);
if (result.IsNullOrEmpty()) if (result.IsNullOrEmpty())
{ {
NoticeManager.Instance.Enqueue(ResUI.OperationFailed); NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
@@ -315,7 +315,7 @@ public partial class RoutingRuleSettingViewModel : MyReactiveObject, ICloseable
private async Task<int> AddBatchRoutingRulesAsync(RoutingItem routingItem, string? clipboardData) private async Task<int> AddBatchRoutingRulesAsync(RoutingItem routingItem, string? clipboardData)
{ {
var blReplace = false; var blReplace = false;
if (await ShowYesNoInteraction.Handle(ResUI.AddBatchRoutingRulesYesNo) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.AddBatchRoutingRulesYesNo) == false)
{ {
blReplace = true; blReplace = true;
} }
@@ -147,7 +147,7 @@ public partial class RoutingSettingViewModel : MyReactiveObject
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeManager.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
} }
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }
@@ -243,7 +243,7 @@ public partial class StatusBarViewModel : MyReactiveObject
sb.AppendLine($"{cmd} HTTPS_PROXY={Global.HttpProtocol}{address}"); sb.AppendLine($"{cmd} HTTPS_PROXY={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} ALL_PROXY={Global.Socks5Protocol}{address}"); sb.AppendLine($"{cmd} ALL_PROXY={Global.Socks5Protocol}{address}");
await SetClipboardDataInteraction.Handle(sb.ToString()); await SetClipboardDataInteraction.HandleSafe(sb.ToString());
} }
private async Task AddServerViaClipboard() private async Task AddServerViaClipboard()
@@ -389,14 +389,7 @@ public partial class StatusBarViewModel : MyReactiveObject
if (blChange) if (blChange)
{ {
try await DispatcherRefreshIconInteraction.HandleSafe(RxVoid.Default);
{
await DispatcherRefreshIconInteraction.Handle(RxVoid.Default);
}
catch (UnhandledInteractionException<RxVoid, RxVoid>)
{
// Ignore
}
} }
} }
@@ -432,7 +425,7 @@ public partial class StatusBarViewModel : MyReactiveObject
{ {
NoticeManager.Instance.SendMessageEx(ResUI.TipChangeRouting); NoticeManager.Instance.SendMessageEx(ResUI.TipChangeRouting);
ReloadRequested.Publish(); ReloadRequested.Publish();
await DispatcherRefreshIconInteraction.Handle(RxVoid.Default); await DispatcherRefreshIconInteraction.HandleSafe(RxVoid.Default);
} }
} }
@@ -469,7 +462,7 @@ public partial class StatusBarViewModel : MyReactiveObject
} }
else else
{ {
var password = await PasswordInputInteraction.Handle(RxVoid.Default); var password = await PasswordInputInteraction.HandleSafe(RxVoid.Default);
if (password.IsNullOrEmpty()) if (password.IsNullOrEmpty())
{ {
_config.TunModeItem.EnableTun = false; _config.TunModeItem.EnableTun = false;
@@ -40,7 +40,7 @@ public partial class SubSettingViewModel : MyReactiveObject
}, canEditRemove); }, canEditRemove);
SubShareCmd = ReactiveCommand.CreateFromTask(async () => SubShareCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await ShareSubInteraction.Handle(SelectedSource?.Url); await ShareSubInteraction.HandleSafe(SelectedSource?.Url);
}, canEditRemove); }, canEditRemove);
_ = Init(); _ = Init();
@@ -84,7 +84,7 @@ public partial class SubSettingViewModel : MyReactiveObject
private async Task DeleteSubAsync() private async Task DeleteSubAsync()
{ {
if (await ShowYesNoInteraction.Handle(ResUI.RemoveServer) == false) if (await ShowYesNoInteraction.HandleSafe(ResUI.RemoveServer) == false)
{ {
return; return;
} }