diff --git a/CHANGELOG.md b/CHANGELOG.md index 3462767..2ea6082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.5.1 (2025-07-29) + +- 🐛 Improved error handling when loading or unloading projects fails. + # 2.5.0 (2023-12-23) - ✨ Filtering options (load dependencies, use regular expressions, etc.) are now stored on a per-solution basis. @@ -5,7 +9,7 @@ # 2.4.1 (2023-08-14) -- 🐛 When using a Solution Filter (`.slnf`), projects would sometimes be hidden in Solution Explorer after they were loaded (#4). +- 🐛 When using a Solution Filter (`.slnf`), projects would sometimes be hidden in Solution Explorer after they were loaded (#4). # 2.4.0 (2022-10-22) diff --git a/Directory.Build.props b/Directory.Build.props index 005d343..39c43ac 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 2.5.0 + 2.5.1 net48 enable 10.0 diff --git a/global.json b/global.json index 4871c2a..f1c37e2 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.200" + "version": "9.0.302" } -} \ No newline at end of file +} diff --git a/source/ProjectFilter/ProjectFilter.csproj b/source/ProjectFilter/ProjectFilter.csproj index bdefbc0..433ed01 100644 --- a/source/ProjectFilter/ProjectFilter.csproj +++ b/source/ProjectFilter/ProjectFilter.csproj @@ -80,7 +80,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -88,7 +88,7 @@ compile; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/source/ProjectFilter/Services/FilterService.cs b/source/ProjectFilter/Services/FilterService.cs index 2cf0e72..9d88821 100644 --- a/source/ProjectFilter/Services/FilterService.cs +++ b/source/ProjectFilter/Services/FilterService.cs @@ -137,19 +137,26 @@ private static async Task UnloadProjectAsync(Guid identifier, State state) { if (IsLoaded(state.Solution, identifier)) { string name; - int result; name = state.Solution.GetName(identifier); state.SetProgressText($"Unloading {name}..."); - result = state.Solution.UnloadProject( - identifier, - (uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser - ); + try { + int result; + + + result = state.Solution.UnloadProject( + identifier, + (uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser + ); - if (ErrorHandler.Failed(result)) { - await LogFailureAsync($"Failed to unload project '{name}'.", result); + if (ErrorHandler.Failed(result)) { + await LogFailureAsync($"Failed to unload project '{name}'.", result); + } + + } catch (Exception ex) when (!ErrorHandler.IsCriticalException(ex)) { + await LogFailureAsync($"Failed to unload project '{name}'.", ex); } state.OnProjectUnloaded(identifier); @@ -166,23 +173,33 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe // visited it before, then we don't need to do anything this time. if (state.ProjectsVisitedWhileLoading.Add(identifier)) { IEnumerable? dependencies; - bool loaded; + bool wasLoaded; dependencies = null; - loaded = false; + wasLoaded = false; if (!IsLoaded(state.Solution, identifier)) { string name; - int result; name = state.Solution.GetName(identifier); state.SetProgressText($"Loading {name}..."); - result = state.Solution.ReloadProject(identifier); - if (ErrorHandler.Failed(result)) { - await LogFailureAsync($"Failed to load project '{name}'.", result); + try { + int result; + + + result = state.Solution.ReloadProject(identifier); + + if (ErrorHandler.Failed(result)) { + await LogFailureAsync($"Failed to load project '{name}'.", result); + return; + } + + } catch (Exception ex) when (!ErrorHandler.IsCriticalException(ex)) { + await LogFailureAsync($"Failed to load project '{name}'.", ex); + return; } // Don't record that we've loaded the project _yet_. If we do that @@ -193,7 +210,7 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe // the progress will increase to 100% and then immediately decrease. // We'll wait until we've recorded that the dependencies need to be // loaded before we record that this project was loaded. - loaded = true; + wasLoaded = true; // Whenever a project is loaded, we should recalculate project dependencies // to ensure that the new project's dependencies are correct. @@ -219,7 +236,7 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe // if we actually loaded the given project, then we can record that // it has been loaded. This prevents the progress from increasing // and then decreasing (instead, it will decrease and then increase). - if (loaded) { + if (wasLoaded) { state.OnProjectLoaded(identifier); } @@ -357,13 +374,21 @@ private static async Task> GetProjectsToCollapseAsync(ISolutio } - private static async Task LogFailureAsync(string message, int result) { + private static Task LogFailureAsync(string message, int result) { + return LogFailureAsync(message, Marshal.GetExceptionForHR(result)); + } + + + private static async Task LogFailureAsync(string message, Exception? ex) { ILogger logger; + string exceptionMessage; logger = await VS.GetRequiredServiceAsync(); - await logger.WriteLineAsync($"{message} {Marshal.GetExceptionForHR(result).Message}"); + exceptionMessage = ex?.Message ?? "[Unknown Error]"; + + await logger.WriteLineAsync($"{message} {exceptionMessage}"); } } diff --git a/tests/ProjectFilter.UnitTests/ProjectFilter.UnitTests.csproj b/tests/ProjectFilter.UnitTests/ProjectFilter.UnitTests.csproj index 4ca9fc5..0fd05bf 100644 --- a/tests/ProjectFilter.UnitTests/ProjectFilter.UnitTests.csproj +++ b/tests/ProjectFilter.UnitTests/ProjectFilter.UnitTests.csproj @@ -1,4 +1,4 @@ - + ProjectFilter @@ -6,16 +6,16 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all