From f6516b9475a99ec90c145f028d07f1403b96b74a Mon Sep 17 00:00:00 2001 From: Moli Date: Tue, 14 Jul 2026 02:36:34 +1000 Subject: [PATCH] fix(commands): handle async void exceptions properly async void methods in command Execute handlers can cause unhandled exceptions that crash the application. This fix extracts the async logic into Task-returning methods and uses HandleExceptions() to ensure exceptions are properly caught and routed to GlobalExceptionHandler, matching the fire-and-forget pattern used throughout the project. Assisted-by: Claude:claude-opus-4-8:Claude Code --- ILSpy/Commands/FileCommands.cs | 14 ++++++++++++-- ILSpy/TreeNodes/AssemblyTreeNode.cs | 7 ++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ILSpy/Commands/FileCommands.cs b/ILSpy/Commands/FileCommands.cs index 016671924f..f8c3aa3f89 100644 --- a/ILSpy/Commands/FileCommands.cs +++ b/ILSpy/Commands/FileCommands.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.Commands [method: ImportingConstructor] sealed class OpenCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand { - public override async void Execute(object? parameter) + public override void Execute(object? parameter) { // Tests / scripted callers can pass paths directly and bypass the file picker. if (parameter is string singlePath) @@ -59,6 +59,11 @@ public override async void Execute(object? parameter) return; } + ExecuteAsync().HandleExceptions(); + } + + async Task ExecuteAsync() + { var owner = UiContext.MainWindow; if (owner == null) return; @@ -236,7 +241,12 @@ internal sealed class SaveCommand( public override bool CanExecute(object? parameter) => assemblyTreeModel.SelectedItem is ILSpyTreeNode; - public override async void Execute(object? parameter) + public override void Execute(object? parameter) + { + ExecuteAsync().HandleExceptions(); + } + + async Task ExecuteAsync() { // Several selected assemblies export a Visual Studio solution (one project each), // matching the Save Code context-menu entry. diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index ba94e57c51..f80576af25 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -675,7 +675,12 @@ public bool IsVisible(TextViewContext context) public bool IsEnabled(TextViewContext context) => true; - public async void Execute(TextViewContext context) + public void Execute(TextViewContext context) + { + ExecuteAsync(context).HandleExceptions(); + } + + async Task ExecuteAsync(TextViewContext context) { if (context.SelectedTreeNodes == null) return;