diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs index 0c007f5a06d..a70289a1c58 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs @@ -877,35 +877,25 @@ private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionE } } - private void CrashGracefully(Exception ex, bool fatal = false) + // CrashGracefully should only be used in the DynamoViewModel class or within tests. + internal void CrashGracefully(Exception ex, bool fatal = false) { try { - - Model.Logger.LogError("CrashGracefully Current ViewModel ID " + this.GetHashCode()); - Model.Logger.LogError("CrashGracefully Current Model ID " + Model.GetHashCode()); - var exceptionAssembly = ex.TargetSite?.Module?.Assembly; + // TargetInvocationException is the exception that is thrown by methods invoked through reflection + // The inner exception contains the originating exception. + // https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/7.0/reflection-invoke-exceptions + if (ex is TargetInvocationException && ex.InnerException != null) + { + exceptionAssembly = ex.InnerException?.TargetSite?.Module?.Assembly; + } + // Do not crash if the exception is coming from a 3d party package; if (!fatal && exceptionAssembly != null) { - Console.WriteLine($"exceptionAssembly + {exceptionAssembly.Location}"); - - Console.WriteLine("PMExtensions.Count" + Model.ExtensionManager.Extensions.OfType().Count()); - Console.WriteLine("PMExtension " + Model.GetPackageManagerExtension()); - Console.WriteLine("PMExtension.PackageLoader " + Model.GetPackageManagerExtension()?.PackageLoader); - Console.WriteLine("PMExtension.PackageLoader.LocalPackages.Count " + Model.GetPackageManagerExtension()?.PackageLoader?.LocalPackages.Count()); - - foreach (var p in Model.GetPackageManagerExtension()?.PackageLoader?.LocalPackages) - { - Console.WriteLine(p.RootDirectory); - Console.WriteLine($"Excepotion from {p.RootDirectory} " + exceptionAssembly.Location.StartsWith(p.RootDirectory, StringComparison.OrdinalIgnoreCase)); - } - // Check if the exception might be coming from a loaded package assembly. var faultyPkg = Model.GetPackageManagerExtension()?.PackageLoader?.LocalPackages?.FirstOrDefault(p => exceptionAssembly.Location.StartsWith(p.RootDirectory, StringComparison.OrdinalIgnoreCase)); - - Console.WriteLine($"FaultyPackage + {faultyPkg?.Name ?? "Not found"}"); if (faultyPkg != null) { var crashDetails = new CrashErrorReportArgs(ex); @@ -914,10 +904,6 @@ private void CrashGracefully(Exception ex, bool fatal = false) return; } } - else - { - Console.WriteLine($"IsCrashing for real"); - } DynamoModel.IsCrashing = true; var crashData = new CrashErrorReportArgs(ex); diff --git a/test/DynamoCoreWpfTests/PackageManager/PackageManagerViewExtensionTests.cs b/test/DynamoCoreWpfTests/PackageManager/PackageManagerViewExtensionTests.cs index 10d3c2e5f91..066fa5a7e08 100644 --- a/test/DynamoCoreWpfTests/PackageManager/PackageManagerViewExtensionTests.cs +++ b/test/DynamoCoreWpfTests/PackageManager/PackageManagerViewExtensionTests.cs @@ -320,56 +320,44 @@ void PackageManagerViewExtensionTests_NotificationLogged(NotificationMessage obj public void TestCrashInPackage() { var pkgDir = Path.Combine(PackagesDirectory, "SampleViewExtension_Crash"); - var currentDynamoModel = ViewModel.Model; - var loader = currentDynamoModel.GetPackageManagerExtension().PackageLoader; var pkg = loader.ScanPackageDirectory(pkgDir); Assert.IsNotNull(pkg); - int count = 0; - void DynamoConsoleLogger_LogErrorToDynamoConsole(string obj) - { - if (obj.Contains("Unhandled exception coming from package")) - { - count++; - } - } - - Assert.IsFalse(DynamoModel.IsCrashing); - - DynamoConsoleLogger.LogErrorToDynamoConsole += DynamoConsoleLogger_LogErrorToDynamoConsole; - - Model.Logger.LogError("Current ViewModel ID " + currentDynamoModel.GetHashCode()); - Model.Logger.LogError("Current Model ID " + Model.GetHashCode()); - + loader.LoadPackages(new List() { pkg }); + + Exception expectedEx = null; + var assem = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name == "TestCrash").FirstOrDefault(); + Assert.IsNotNull(assem); - NotImplementedException expectedEx = null; try { - loader.LoadPackages(new List() { pkg }); - DispatcherUtil.DoEventsLoop(() => count > 0); + assem.GetType("TestCrash.Class1").GetMethod("TestCrash").Invoke(null, new object[] { }); } - catch (NotImplementedException ex) + catch (Exception ex) { expectedEx = ex; } - var loadedPkg = currentDynamoModel.GetPackageManagerExtension()?.PackageLoader?.LocalPackages?.FirstOrDefault(p => + int count = 0; + void DynamoConsoleLogger_LogErrorToDynamoConsole(string obj) { - return p.RootDirectory.EndsWith("SampleViewExtension_Crash", StringComparison.OrdinalIgnoreCase); - }); + if (obj.Contains($"Unhandled exception coming from package {pkg.Name} was handled")) + { + count++; + } + } - Assert.AreEqual(PackageLoadState.StateTypes.Loaded, loadedPkg.LoadState.State); + DynamoConsoleLogger.LogErrorToDynamoConsole += DynamoConsoleLogger_LogErrorToDynamoConsole; - Assert.IsNotNull(expectedEx); - Assert.IsNotNull(expectedEx.TargetSite?.Module?.Assembly); - Assert.IsTrue(expectedEx.TargetSite?.Module?.Assembly.Location.StartsWith(pkg.RootDirectory, StringComparison.OrdinalIgnoreCase)); - Assert.IsFalse(DynamoModel.IsCrashing); - Assert.AreEqual(1, count); + ViewModel.CrashGracefully(expectedEx); DynamoConsoleLogger.LogErrorToDynamoConsole -= DynamoConsoleLogger_LogErrorToDynamoConsole; + + ViewModel.CrashGracefully(expectedEx); + Assert.AreEqual(1, count); } [OneTimeTearDown] diff --git a/test/pkgs/SampleViewExtension_Crash/bin/SampleViewExtensionCrash.dll b/test/pkgs/SampleViewExtension_Crash/bin/SampleViewExtensionCrash.dll index 00962a6becb..dd8610affec 100644 Binary files a/test/pkgs/SampleViewExtension_Crash/bin/SampleViewExtensionCrash.dll and b/test/pkgs/SampleViewExtension_Crash/bin/SampleViewExtensionCrash.dll differ