From 6b54ca28b0db9af12ab08a8161abe8c70808e971 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 4 Jun 2025 12:32:57 +0800 Subject: [PATCH 1/6] Silent handle TaskSchedulerUnobservedTaskException --- Flow.Launcher/Helper/ErrorReporting.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Helper/ErrorReporting.cs b/Flow.Launcher/Helper/ErrorReporting.cs index aa810ba65..7d2a1216f 100644 --- a/Flow.Launcher/Helper/ErrorReporting.cs +++ b/Flow.Launcher/Helper/ErrorReporting.cs @@ -11,10 +11,11 @@ namespace Flow.Launcher.Helper; public static class ErrorReporting { - private static void Report(Exception e, [CallerMemberName] string methodName = "UnHandledException") + private static void Report(Exception e, bool silent = false, [CallerMemberName] string methodName = "UnHandledException") { var logger = LogManager.GetLogger(methodName); logger.Fatal(ExceptionFormatter.FormatExcpetion(e)); + if (silent) return; var reportWindow = new ReportWindow(e); reportWindow.Show(); } @@ -36,7 +37,7 @@ public static class ErrorReporting public static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { // handle unobserved task exceptions on UI thread - Application.Current.Dispatcher.Invoke(() => Report(e.Exception)); + Application.Current.Dispatcher.Invoke(() => Report(e.Exception, true)); // prevent application exit, so the user can copy the prompted error info e.SetObserved(); } From 2582a9fa2091d45f74981469aad2e747f5841669 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 4 Jun 2025 13:31:41 +0800 Subject: [PATCH 2/6] Log exception instead of reporting --- Flow.Launcher/Helper/ErrorReporting.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Helper/ErrorReporting.cs b/Flow.Launcher/Helper/ErrorReporting.cs index 7d2a1216f..e201284cb 100644 --- a/Flow.Launcher/Helper/ErrorReporting.cs +++ b/Flow.Launcher/Helper/ErrorReporting.cs @@ -1,10 +1,10 @@ using System; using System.Runtime.CompilerServices; using System.Threading.Tasks; -using System.Windows; using System.Windows.Threading; using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Exception; +using Flow.Launcher.Infrastructure.Logger; using NLog; namespace Flow.Launcher.Helper; @@ -36,8 +36,9 @@ public static class ErrorReporting public static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { - // handle unobserved task exceptions on UI thread - Application.Current.Dispatcher.Invoke(() => Report(e.Exception, true)); + // log exception but do not handle unobserved task exceptions on UI thread + //Application.Current.Dispatcher.Invoke(() => Report(e.Exception, true)); + Log.Exception(nameof(ErrorReporting), "Unobserved task exception occurred.", e.Exception); // prevent application exit, so the user can copy the prompted error info e.SetObserved(); } From bdd349e24201107990e84a5b11436753f3a051e4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 4 Jun 2025 13:39:11 +0800 Subject: [PATCH 3/6] Improve format --- Flow.Launcher/PublicAPIInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index c06c56039..7f0b03445 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -251,7 +251,7 @@ namespace Flow.Launcher Http.GetStreamAsync(url, token); public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, - CancellationToken token = default) =>Http.DownloadAsync(url, filePath, reportProgress, token); + CancellationToken token = default) => Http.DownloadAsync(url, filePath, reportProgress, token); public void AddActionKeyword(string pluginId, string newActionKeyword) => PluginManager.AddActionKeyword(pluginId, newActionKeyword); From 8737217513dd1e6791fc282452e0cb0cdef246bf Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 4 Jun 2025 13:44:10 +0800 Subject: [PATCH 4/6] Show error message --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index a16778ff4..5d20fab01 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -436,7 +436,7 @@ namespace Flow.Launcher.Plugin.PluginsManager catch (Exception ex) { Context.API.LogException(ClassName, $"Update failed for {plugin.Name}", ex.InnerException); - Context.API.ShowMsg( + Context.API.ShowMsgError( Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), string.Format( Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), From f60585f609b3d908eea89980f393fe823c65f9ef Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 4 Jun 2025 13:44:50 +0800 Subject: [PATCH 5/6] Use try-catch to handle download issue --- .../PluginsManager.cs | 108 ++++++++++-------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 5d20fab01..25182f6d3 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -316,61 +316,75 @@ namespace Flow.Launcher.Plugin.PluginsManager var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{x.Name}-{x.NewVersion}.zip"); - _ = Task.Run(async delegate + _ = Task.Run(async () => { - using var cts = new CancellationTokenSource(); + try + { + using var cts = new CancellationTokenSource(); - if (!x.PluginNewUserPlugin.IsFromLocalInstallPath) - { - await DownloadFileAsync( - $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}", - x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts); - } - else - { - downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath; - } - - // check if user cancelled download before installing plugin - if (cts.IsCancellationRequested) - { - return; - } - else - { - await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin, - downloadToFilePath); - - if (Settings.AutoRestartAfterChanging) + if (!x.PluginNewUserPlugin.IsFromLocalInstallPath) { - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format( - Context.API.GetTranslation( - "plugin_pluginsmanager_update_success_restart"), - x.Name)); - Context.API.RestartApp(); + await DownloadFileAsync( + $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}", + x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts); } else { - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format( - Context.API.GetTranslation( - "plugin_pluginsmanager_update_success_no_restart"), - x.Name)); + downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath; + } + + // check if user cancelled download before installing plugin + if (cts.IsCancellationRequested) + { + return; + } + else + { + await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin, + downloadToFilePath); + + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_restart"), + x.Name)); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_no_restart"), + x.Name)); + } } } - }).ContinueWith(t => - { - Context.API.LogException(ClassName, $"Update failed for {x.Name}", - t.Exception.InnerException); - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - x.Name)); - }, token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); + catch (HttpRequestException e) + { + // show error message + Context.API.ShowMsgError( + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), x.Name), + Context.API.GetTranslation("plugin_pluginsmanager_download_error")); + Context.API.LogException(ClassName, "An error occurred while downloading plugin", e); + return; + } + catch (Exception e) + { + // show error message + Context.API.LogException(ClassName, $"Update failed for {x.Name}", e); + Context.API.ShowMsgError( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + x.Name)); + return; + } + }); return true; }, From 93b3ac4b891cccc5b8c8337183dfbf1da3c49470 Mon Sep 17 00:00:00 2001 From: DB P Date: Wed, 4 Jun 2025 18:28:50 +0900 Subject: [PATCH 6/6] Add PendingLineStyle based on BasePendingLineStyle for improved styling --- Flow.Launcher/Themes/Base.xaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Flow.Launcher/Themes/Base.xaml b/Flow.Launcher/Themes/Base.xaml index e531c17ad..a5ded7e59 100644 --- a/Flow.Launcher/Themes/Base.xaml +++ b/Flow.Launcher/Themes/Base.xaml @@ -108,6 +108,10 @@ +