From d3fdd99e1085b10480d12fd660f89ba5b7f7d50f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 9 Apr 2025 18:09:54 +0800 Subject: [PATCH 1/4] Fix ConnectionLostException for JsonRPC v2 plugins --- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 18 +++------------ .../Plugin/JsonRPCPluginBase.cs | 4 ++-- Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 22 ++++++++++++++----- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index 88d595301be..9f64e418ca7 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -1,5 +1,4 @@ -using Flow.Launcher.Core.Resource; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -7,10 +6,10 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Flow.Launcher.Core.Resource; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Plugin; using Microsoft.IO; -using System.Windows; namespace Flow.Launcher.Core.Plugin { @@ -20,7 +19,7 @@ namespace Flow.Launcher.Core.Plugin /// internal abstract class JsonRPCPlugin : JsonRPCPluginBase { - public const string JsonRPC = "JsonRPC"; + public new const string JsonRPC = "JsonRPC"; protected abstract Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default); protected abstract string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default); @@ -29,9 +28,6 @@ internal abstract class JsonRPCPlugin : JsonRPCPluginBase private int RequestId { get; set; } - private string SettingConfigurationPath => Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml"); - private string SettingPath => Path.Combine(Context.CurrentPluginMetadata.PluginSettingsDirectoryPath, "Settings.json"); - public override List LoadContextMenus(Result selectedResult) { var request = new JsonRPCRequestModel(RequestId++, @@ -57,13 +53,6 @@ public override List LoadContextMenus(Result selectedResult) } }; - private static readonly JsonSerializerOptions settingSerializeOption = new() - { - WriteIndented = true - }; - - private readonly Dictionary _settingControls = new(); - private async Task> DeserializedResultAsync(Stream output) { await using (output) @@ -122,7 +111,6 @@ protected override async Task ExecuteResultAsync(JsonRPCResult result) return !result.JsonRPCAction.DontHideAfterAction; } - /// /// Execute external program and return the output /// diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index 779dcf887d8..b134e2d50fe 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -1,11 +1,11 @@ -using Flow.Launcher.Core.Resource; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Flow.Launcher.Core.Resource; using Flow.Launcher.Plugin; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs index abe563c145a..d240ac9bef2 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs @@ -10,7 +10,6 @@ using StreamJsonRpc; using IAsyncDisposable = System.IAsyncDisposable; - namespace Flow.Launcher.Core.Plugin { internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, IAsyncReloadable, IResultUpdated @@ -23,7 +22,6 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I private JsonRpc RPC { get; set; } - protected override async Task ExecuteResultAsync(JsonRPCResult result) { var res = await RPC.InvokeAsync(result.JsonRPCAction.Method, @@ -55,7 +53,6 @@ public override async Task> QueryAsync(Query query, CancellationTok return results; } - public override async Task InitAsync(PluginInitContext context) { await base.InitAsync(context); @@ -88,7 +85,6 @@ protected enum MessageHandlerType protected abstract MessageHandlerType MessageHandler { get; } - private void SetupJsonRPC() { var formatter = new SystemTextJsonFormatter { JsonSerializerOptions = RequestSerializeOption }; @@ -118,9 +114,16 @@ public virtual async Task ReloadDataAsync() { await RPC.InvokeAsync("reload_data", Context); } - catch (RemoteMethodNotFoundException e) + catch (RemoteMethodNotFoundException) + { + } + catch (ConnectionLostException) { } + catch (Exception e) + { + Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call reload_data", e); + } } public virtual async ValueTask DisposeAsync() @@ -129,8 +132,15 @@ public virtual async ValueTask DisposeAsync() { await RPC.InvokeAsync("close"); } - catch (RemoteMethodNotFoundException e) + catch (RemoteMethodNotFoundException) + { + } + catch (ConnectionLostException) + { + } + catch (Exception e) { + Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call close", e); } finally { From 8730a5fce8079a955a98533307c8c91383ce1f95 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 9 Apr 2025 18:10:44 +0800 Subject: [PATCH 2/4] Improve log message --- Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs index d240ac9bef2..eda016d9401 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs @@ -122,7 +122,7 @@ public virtual async Task ReloadDataAsync() } catch (Exception e) { - Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call reload_data", e); + Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e); } } @@ -140,7 +140,7 @@ public virtual async ValueTask DisposeAsync() } catch (Exception e) { - Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call close", e); + Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e); } finally { From 4095eb4b86cccca1d9be969c0cac59e52b48dd64 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 9 Apr 2025 19:26:52 +0800 Subject: [PATCH 3/4] Improve code quality --- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 17 +++++++++-------- Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 7 ++----- Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 6 ++++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index 9f64e418ca7..b19bb6c79af 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Flow.Launcher.Core.Resource; -using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Plugin; using Microsoft.IO; @@ -21,6 +20,8 @@ internal abstract class JsonRPCPlugin : JsonRPCPluginBase { public new const string JsonRPC = "JsonRPC"; + private static readonly string ClassName = nameof(JsonRPCPlugin); + protected abstract Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default); protected abstract string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default); @@ -148,11 +149,11 @@ protected string Execute(ProcessStartInfo startInfo) var error = standardError.ReadToEnd(); if (!string.IsNullOrEmpty(error)) { - Log.Error($"|JsonRPCPlugin.Execute|{error}"); + Context.API.LogError(ClassName, error); return string.Empty; } - Log.Error("|JsonRPCPlugin.Execute|Empty standard output and standard error."); + Context.API.LogError(ClassName, "Empty standard output and standard error."); return string.Empty; } @@ -160,8 +161,8 @@ protected string Execute(ProcessStartInfo startInfo) } catch (Exception e) { - Log.Exception( - $"|JsonRPCPlugin.Execute|Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", + Context.API.LogException(ClassName, + $"Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", e); return string.Empty; } @@ -172,7 +173,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati using var process = Process.Start(startInfo); if (process == null) { - Log.Error("|JsonRPCPlugin.ExecuteAsync|Can't start new process"); + Context.API.LogError(ClassName, "Can't start new process"); return Stream.Null; } @@ -192,7 +193,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati } catch (Exception e) { - Log.Exception("|JsonRPCPlugin.ExecuteAsync|Exception when kill process", e); + Context.API.LogException(ClassName, "Exception when kill process", e); } }); @@ -213,7 +214,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati { case (0, 0): const string errorMessage = "Empty JSON-RPC Response."; - Log.Warn($"|{nameof(JsonRPCPlugin)}.{nameof(ExecuteAsync)}|{errorMessage}"); + Context.API.LogWarn(ClassName, errorMessage); break; case (_, not 0): throw new InvalidDataException(Encoding.UTF8.GetString(errorBuffer.ToArray())); // The process has exited with an error message diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index b134e2d50fe..df0438409f3 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -19,10 +19,9 @@ namespace Flow.Launcher.Core.Plugin /// public abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable { - protected PluginInitContext Context; public const string JsonRPC = "JsonRPC"; - private int RequestId { get; set; } + protected PluginInitContext Context; private string SettingConfigurationPath => Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml"); @@ -107,7 +106,6 @@ protected void ExecuteFlowLauncherAPI(string method, object[] parameters) public abstract Task> QueryAsync(Query query, CancellationToken token); - private async Task InitSettingAsync() { JsonRpcConfigurationModel configuration = null; @@ -119,7 +117,6 @@ private async Task InitSettingAsync() await File.ReadAllTextAsync(SettingConfigurationPath)); } - Settings ??= new JsonRPCPluginSettings { Configuration = configuration, SettingPath = SettingPath, API = Context.API @@ -130,7 +127,7 @@ private async Task InitSettingAsync() public virtual async Task InitAsync(PluginInitContext context) { - this.Context = context; + Context = context; await InitSettingAsync(); } diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs index eda016d9401..6dccfa59b1a 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs @@ -16,6 +16,8 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I { public const string JsonRpc = "JsonRPC"; + private static readonly string ClassName = nameof(JsonRPCPluginV2); + protected abstract IDuplexPipe ClientPipe { get; set; } protected StreamReader ErrorStream { get; set; } @@ -122,7 +124,7 @@ public virtual async Task ReloadDataAsync() } catch (Exception e) { - Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e); + Context.API.LogException(ClassName, $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e); } } @@ -140,7 +142,7 @@ public virtual async ValueTask DisposeAsync() } catch (Exception e) { - Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e); + Context.API.LogException(ClassName, $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e); } finally { From 5a2db37d39fcd1c614e06e7d54a938bc37a9d3b3 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 9 Apr 2025 19:43:22 +0800 Subject: [PATCH 4/4] Add code comments --- Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs index 6dccfa59b1a..148fd969e49 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs @@ -118,9 +118,11 @@ public virtual async Task ReloadDataAsync() } catch (RemoteMethodNotFoundException) { + // Ignored } catch (ConnectionLostException) { + // Ignored } catch (Exception e) { @@ -136,9 +138,11 @@ public virtual async ValueTask DisposeAsync() } catch (RemoteMethodNotFoundException) { + // Ignored } catch (ConnectionLostException) { + // Ignored } catch (Exception e) {