From a9be69dce5405f9d19e3e37448fee8b5bf61b05c Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Thu, 29 Jan 2026 14:24:08 -0500 Subject: [PATCH] fix(command): add error handling for Execute method Add comprehensive error handling to the Execute method to prevent silent failures and provide user feedback when the command fails. Changes: - Wrap telemetry initialization in try-catch to prevent blocking - Show error dialog when DTE service is unavailable - Show error dialog when Solution Explorer selection fails - Inform users when no project is selected - Inform users when selected item is not a project - Catch unexpected exceptions and display with issue report link - Properly dispose telemetry activity in finally block Fixes #60 --- .../Commands/RenamifyProjectCommand.cs | 87 +++++++++++++++++-- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs index f1fc5b5..3b49bcb 100644 --- a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs +++ b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs @@ -46,20 +46,91 @@ private void Execute(object sender, EventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); - using var activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.Execute"); - - if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte)) + IDisposable activity = null; + try { - return; + activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.Execute"); + } + catch (Exception ex) + { + // Telemetry initialization failed - log but continue + System.Diagnostics.Debug.WriteLine($"Telemetry initialization failed: {ex.Message}"); } - var selectedItems = (Array)dte.ToolWindows.SolutionExplorer.SelectedItems; - foreach (UIHierarchyItem selectedItem in selectedItems) + try { - if (selectedItem.Object is Project project) + if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte)) + { + System.Windows.MessageBox.Show( + "Unable to access Visual Studio automation services (DTE).\n\n" + + "Please try again or restart Visual Studio.", + "Project Renamifier", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Warning); + return; + } + + Array selectedItems; + try + { + selectedItems = (Array)dte.ToolWindows.SolutionExplorer.SelectedItems; + } + catch (Exception ex) { - RenameProject(project, dte); + System.Windows.MessageBox.Show( + $"Unable to access Solution Explorer selection.\n\n{ex.Message}", + "Project Renamifier", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Warning); + return; } + + if (selectedItems == null || selectedItems.Length == 0) + { + System.Windows.MessageBox.Show( + "No project is selected.\n\nPlease select a project in Solution Explorer and try again.", + "Project Renamifier", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Information); + return; + } + + var projectFound = false; + foreach (UIHierarchyItem selectedItem in selectedItems) + { + if (selectedItem.Object is Project project) + { + projectFound = true; + RenameProject(project, dte); + } + } + + if (!projectFound) + { + System.Windows.MessageBox.Show( + "The selected item is not a project.\n\nPlease select a project (not a solution folder or file) and try again.", + "Project Renamifier", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Information); + } + } + catch (Exception ex) + { + VsixTelemetry.TrackException(ex, new Dictionary + { + { "operation.name", "Execute" } + }); + + System.Windows.MessageBox.Show( + $"An unexpected error occurred:\n\n{ex.Message}\n\n" + + "Please report this issue at:\nhttps://github.com/CodingWithCalvin/VS-ProjectRenamifier/issues", + "Project Renamifier - Error", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Error); + } + finally + { + activity?.Dispose(); } }