-
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
crash report fixes #15147
crash report fixes #15147
Conversation
UI Smoke TestsTest: success. 2 passed, 0 failed. |
@@ -839,6 +839,18 @@ private void CrashGracefully(Exception ex, bool fatal = false) | |||
{ | |||
try | |||
{ | |||
if (!fatal) | |||
{ | |||
var localPkg = Model.GetPackageManagerExtension()?.PackageLoader?.LocalPackages?.FirstOrDefault(p => p.LoadedAssemblies.FirstOrDefault(a => a.Name == ex.Source) != null); |
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.
might happen that one of these package assemblies is already loaded by dynamo (as a dependency), so we could potentially continue running even though the exception is coming from somewhere else. (not the pacakge we identified)
But I think that might be an edge case.
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.
At the moment this code will always continue the session and only log the exception.
As an alternative, we could show a warning message that exception ex was thrown from package X and give the user a choice to continue the dynamo seasion or crash and send CER report
@Amoursol any preferences?
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.
If the source property is not set explicitly, the runtime automatically sets it to the name of the assembly in which the exception originated.
hmm, so in most cases this will work.
Have you verified that this property is set to the short name or full name of the assembly? Does it include the version number and culture?
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.
what about the edge case where a user has shipped system binaries (Microsoft) or Dynamo binaries?
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.
what about also logging something to ADP so we have analytics on how often these crashes occur without actually crashing?
whoops missed your call to track!
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.
Have you verified that this property is set to the short name or full name of the assembly
It is just the short name. Obviously this can be overridden by custom exceptions.
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.
what about the edge case where a user has shipped system binaries (Microsoft) or Dynamo binaries?
Not sure at the moment how I can identify these sort of cases...Are the package LoadedAssemblies
actually loaded or they can just be on disk without actually being the ones to be loaded...I can check this
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.
Yea, LoadedAssemblies
could be already loaded assemblies. So if a user supplies a dotnet system dll, then all the exceptions from that dll (even if it was loaded by dotnet previously) will not cause a hard crash anymore.
I can verify if the assemblies have been loaded already, probably at a small performance penalty
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.
Minor: does it still make sense to have this check (code path) in the same function (CrashGracefully
), as it isn't crashing in this case?
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.
CrashGracefully is called from multiple places.
Another way I could go is to not subscribe to the unhandled_exception_handlers at all during testing. But I think the logging is still valuable for debugging. So I suggest we leave the rethrow in the CrashGracefully method for now
Only the removePII fails (as in master) https://master-5.jenkins.autodesk.com/job/Dynamo/job/DynamoSelfServe/job/pullRequestValidation/15886/ |
{ | ||
DynamoViewModel dynamoViewModel = sender as DynamoViewModel; |
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.
nit pick - use var
also pattern match is
would be nice with an if statement for the second line.
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.
you mean like so ?
DynamoModel model = null;
var dynamoViewModel = sender as DynamoViewModel;
if (dynamoViewModel != null)
{
model = dynamoViewModel.Model;
}
else if (sender is DynamoModel dm)
{
model = dm;
}
can you add a test for this by raising a mocked exception and setting source explicitly to the name of an assembly in one of the packages we load by default during tests? |
Sure can. Totally forgot about tests.. |
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.
Can you give some context to why was the crash happening in the first place?
The exception is thrown somewhere in the juggnernaut assemblies. Not sure what. |
Is the crash because an assembly that's already loaded is trying to be loaded again because it's a dependency of a package? |
No, it is just a null reference exceptions or something similar |
src/DynamoPackages/Package.cs
Outdated
List<string> appDomainAssemblies = null; | ||
var binFiles = new DirectoryInfo(BinaryDirectory).EnumerateFiles("*.dll"); | ||
if (binFiles.Any()) { | ||
appDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(x => x.GetName().Name).ToList(); |
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.
hopefully not too much of a performance hit here.
This will run for every loaded pkg that has at least one binary on disk.
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.
If I try to move this a level up, the assembly list might change (because we iterate all the types and dependencies might get loaded)
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.
have you considered how ALCs and packages containing extensions or binaries in other folders might affect this check?
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.
Also I am still curious about the name property of the assembly, does that contain the version number or not?
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 did not consider those. THanks !
binaries in other folders might affect this check?
- CHanged the code to check if the faulty assembly is inside the package root folder.
ALCs
- Changed the code to use TargetSite.Module.Assembly - Gets the method(and assembly) where the exception was thrown - https://learn.microsoft.com/en-us/dotnet/api/system.exception.targetsite?view=net-8.0 (not sure why I did not see this before)
curious about the name property of the assembly
- I am now using the equality operator on assemblies which should consider version and culture and ALCs
if (DynamoModel.IsTestMode) | ||
{ | ||
// Do not handle the exception in test mode. | ||
// Let the test host handle it. |
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.
You might have covered this at standup but can you remind me again what you see in tests if the exception is marked as handled?
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.
If (during tests) the exception is marked as handled inside the ex_handler, then the test that threw the exception might pass (as if nothing was thrown)
Our tests have a single entry point for async tasks (we run these with DispatcherUtil.DoLoop). Whenever an async task throws an exception (and if unhandled) it will propagate until the DIspatcherUtil.DoLoop calls and eventually be caught by the nunit test runner
@pinzart90 your new test is failing. Can you check? You might already be on top of it but I'm monitoring the builds this week ;) |
DYN-4849 - Handle exceptions coming from 3d party packages.
Fix sender object on Crash handlers
Only handle exceptions coming from assemblies that were loaded from a 3rd party package
Skip crash window and rethrow exceptions during tests
Removed feature flag for CER (will always be on)