-
Notifications
You must be signed in to change notification settings - Fork 635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DYN-6492 add unhandled exception handler to viewmodel #14840
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
using System.Windows.Media; | ||
using System.Windows.Threading; | ||
using Dynamo.Configuration; | ||
using Dynamo.Core; | ||
using Dynamo.Engine; | ||
using Dynamo.Exceptions; | ||
using Dynamo.Graph; | ||
|
@@ -22,6 +23,7 @@ | |
using Dynamo.Graph.Nodes; | ||
using Dynamo.Graph.Workspaces; | ||
using Dynamo.Interfaces; | ||
using Dynamo.Logging; | ||
using Dynamo.Models; | ||
using Dynamo.PackageManager; | ||
using Dynamo.PackageManager.UI; | ||
|
@@ -30,7 +32,6 @@ | |
using Dynamo.Services; | ||
using Dynamo.UI; | ||
using Dynamo.UI.Prompts; | ||
using Dynamo.Updates; | ||
using Dynamo.Utilities; | ||
using Dynamo.Visualization; | ||
using Dynamo.Wpf.Interfaces; | ||
|
@@ -675,6 +676,8 @@ public struct StartConfiguration | |
|
||
protected DynamoViewModel(StartConfiguration startConfiguration) | ||
{ | ||
Dispatcher.CurrentDispatcher.UnhandledException += CurrentDispatcher_UnhandledException; | ||
|
||
this.ShowLogin = startConfiguration.ShowLogin; | ||
|
||
// initialize core data structures | ||
|
@@ -754,6 +757,33 @@ protected DynamoViewModel(StartConfiguration startConfiguration) | |
FileTrustViewModel = new FileTrustWarningViewModel(); | ||
} | ||
|
||
private void CurrentDispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) | ||
{ | ||
if (e.Handled) | ||
{ | ||
return; | ||
} | ||
|
||
e.Handled = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Marking it as handled will mean other handlers will no longer be called anymore. Ex D4R will exception Handler will no longer be called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, as discussed, this needs some design so host-specific shutdown/cleanup steps can be taken into account in this handler. WIP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Correction: I was wrong about the previous comment. I saw the handler in D4R being called earlier since another exception was being thrown while the exception was being handled in I have removed the same handler from D4R, see my PR in DynamoRevit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, looks like there is another handler that can mark exceptions as “handled” https://learn.microsoft.com/en-us/dotnet/api/system.windows.threading.dispatcher.unhandledexceptionfilter?view=windowsdesktop-8.0 not sure what we could do with it(or how to use it). Maybe mark dynamo VM exceptions as handled so the app just continues and we only log(somehow). Probably for another time.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VM exceptions are usually non-recoverable. They are signs of the VM being corrupt most of the time so it's wise to shutdown and restart Dynamo in those cases. Still worth taking a look at this. Thanks. |
||
CrashGracefully(e.Exception); | ||
pinzart90 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private void CrashGracefully(Exception ex) | ||
{ | ||
try | ||
{ | ||
Model?.Logger?.LogError($"Unhandled exception {ex.Message}"); | ||
|
||
DynamoModel.IsCrashing = true; | ||
Analytics.TrackException(ex, true); | ||
Model?.OnRequestsCrashPrompt(new CrashErrorReportArgs(ex)); | ||
|
||
Exit(false); // don't allow cancellation | ||
} | ||
catch | ||
{ } | ||
} | ||
|
||
/// <summary> | ||
/// Sets up the provided <see cref="DefaultWatch3DViewModel"/> object and | ||
/// adds it to the Watch3DViewModels collection. | ||
|
@@ -3412,6 +3442,8 @@ public ShutdownParams( | |
/// | ||
public bool PerformShutdownSequence(ShutdownParams shutdownParams) | ||
{ | ||
Dispatcher.CurrentDispatcher.UnhandledException -= CurrentDispatcher_UnhandledException; | ||
aparajit-pratap marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (shutdownSequenceInitiated) | ||
{ | ||
// There was a prior call to shutdown. This could happen for example | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pinzart90 does it make sense to also subscribe to the appdomain exception event here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure where we should put this handler. Theoretically it should be added as soon as possible in the application lifecycle so that more exceptions can be handled.
Also this handler will not catch exceptions coming from other threads. THat is where AppDomain.UNhandledException would come in handy. However it seems a bit risky since it could be called in non UI threads (at least that's what I;ve noticed in my testing)