Skip to content
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

App on Microsoft Store runs fine on most user systems but fails to run on others with a stowed exception being reported in MS Partner Center #4861

Closed
RDMacLachlan opened this issue Nov 8, 2024 · 10 comments
Labels
area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) needs-author-feedback no-recent-activity

Comments

@RDMacLachlan
Copy link
Member

RDMacLachlan commented Nov 8, 2024

Discussed in:

Originally posted by JosHuybrighs November 6, 2024
This is probably not the right place to have this discussion but I don't know where else I can bring this up.
I have a desktop app on the Microsoft Store that uses the WinAppSDK and runs successfully on most of the user's computers.
For some systems however the Microsoft Partner Center's health section for the app shows a lot of 'stowed exceptions' occurring when the application is being started.

The stack trace is only:

0 Microsoft.ui.xaml.dll   DirectUI::FrameworkApplication::StartDesktop    0x0000000000195D30
1 Microsoft.ui.xaml.dll   DirectUI::FrameworkApplicationFactory::Start    0x0000000000000070

Some have a minidump file attached which when analyzing with WinDbg shows:

STACK_TEXT:  
0000022b`ddafc7c0 00007ff9`4f7bcbef combase!RoOriginateLanguageException+0x5f
STACK_COMMAND:  *** Stowed Exception v2 ***; .exr -1; dpp 0x22bddafce20 L0x2; dt 0x22be437e168 combase!STOWED_EXCEPTION_INFORMATION_V2 -r; dps 0x22bddafc7c0 L0x2; *** Nested 'LEO1' @ 0x22BBCAFD628 ***; *** NOSOS *** ; ** Pseudo Context ** StowedPseudo ** Value: 25533b22ce0 *
FAULTING_SOURCE_LINE:  onecore\com\combase\winrt\error\error.cpp
FAULTING_SOURCE_FILE:  onecore\com\combase\winrt\error\error.cpp
FAULTING_SOURCE_LINE_NUMBER:  1517
FAULTING_SOURCE_SRV_COMMAND:  https://dev.azure.com/microsoft/OS/_apis/git/repositories/os.2020/items?path=/onecore/com/combase/winrt/error/error.cpp&versionDescriptor.versionType=commit&versionDescriptor.version=d1ef9e76dc48ba4fc8ee663062ec9a2cec78ee77&versionDescriptor.options=none&download=true&api-version=2.0
SYMBOL_NAME:  combase!RoOriginateLanguageException+5f
MODULE_NAME: combase
IMAGE_NAME:  combase.dll
FAILURE_BUCKET_ID:  STOWED_EXCEPTION_NOSOS_8000ffff_combase.dll!RoOriginateLanguageException

I understand that the error is most likely due to an unhandled exception within a WinRT or COM API which my application is calling.
To trap those exceptions the app constructor takes care of this like so (I am using MS AppCenter to track faults):

public App()
{
    sAppInstance = this;
    this.InitializeComponent();

    // Initialize logger
    EnableLogging();

    // Enable AppCenter
    EnableAppCenter();

    // Subscribe for unhandled exceptions
    UnhandledException += (object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) =>
    {
        e.Handled = true;
        AppUnhandledException(e.Exception);
    }; 
    TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs e) => AppUnhandledException(e.Exception);
   ...
}

AppUnhandledException(e.Exception) makes a large string of the stack and sends it in chunks to MS AppCenter.

I don't get anything however in MS AppCenter that relates to DirectUI::FrameworkApplication::StartDesktop.

So, are there any suggestions how to deal with this?
I just saw myself that it is probably better to do EnableLogging() (it accesses ApplicationDataContainer in local settings to see if logging is enabled) after the registration for unhandled events and so I will do that in the next update of the app and see what it gives.

In the mean time however what remains important: on most user's system this error doesn't come up. Why on others? The app is deployed selfcontained and so I have to expect that there shouldn't be any wrong or missing DLLs in the package.
Or is it not that simple?

I keep thinking that a WinAppSDK/WinUI desktop app needs certain dlls in Windows that are not part of the package but aren't necessarily available on a user's system. If so, shouldnt there be an error when the app is being installed?

@RDMacLachlan
Copy link
Member Author

This was created from Discussion #4853.

@RDMacLachlan
Copy link
Member Author

Hi @JosHuybrighs,
Can you run Feedback Hub and report the logs and crash dump from the experience.

@JosHuybrighs
Copy link

@RDMacLachlan

I reported the exception in Feedback Hub 5 minutes ago. A minidump file is attached.

@RDMacLachlan
Copy link
Member Author

@JosHuybrighs Please include a link to the feedback hub issue you created.

@JosHuybrighs
Copy link

@RDMacLachlan

See Feedback Hub

@KevinLaMS KevinLaMS added the area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) label Nov 25, 2024
@KevinLaMS
Copy link
Collaborator

Michael will take a looksee

@codendone
Copy link
Contributor

Thanks for sharing a dump, @JosHuybrighs! I stored some additional notes about it in this (internal tracking issue).

The minidump doesn't contain many clues. It shows a C# exception was thrown during initialization and XAML's DirectUI::FrameworkApplication::StartDesktop() recorded that as a fatal error. The exception is thrown in the Start initialization function, which by default looks like this:

    global::Microsoft.UI.Xaml.Application.Start((p) => {
        var context = new global::Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext(global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread());
        global::System.Threading.SynchronizationContext.SetSynchronizationContext(context);
        new App();
    });

The only possibilities are that the exception happened during those lines before the App construction or that it happened somewhere during the App construction. In analyzing the code, I don't see any possibility for this specific exception to be thrown by DispatcherQueue.GetForCurrentThread, or DispatcherQueueSynchronizationContext, or SetSynchronizationContext. Unless I missed something, that means this most likely happened in the App constructor.

It might be helpful to add a try/catch in the constructor, though I'd expect your UnhandledException handler to still see something if you successfully registered that.

Any member variables on the App which are initialized by default may also be opportunities for a failure, though. It might be worth reviewing those, and moving initialization into the constructor for any which have a higher risk of failure.

If you're using custom initialization instead of XAML's generated Main function, then you should also look at anything custom done there.

@RDMacLachlan
Copy link
Member Author

@JosHuybrighs were the comments from codendone helpful? If not, can you provide a repro.

@JosHuybrighs
Copy link

@RDMacLachlan

were the comments from codendone helpful? If not, can you provide a repro.

The comments definitely clarified certain things. In the mean time I have reworked the App's constructor to delay some of the more complicated initialization stuff to the OnLaunched method. The update is published but I still see the stowed exception being reported in Microsoft Partner Center (in the Health section). Unfortunately Partner Center doesn't show for which version of the app this is occurring. Might as well be for one of the previous versions.

For your information, the App's constructor looks as follows:

public App()
{
	// Enable AppCenter
	EnableAppCenter();

	// Subscribe for unhandled exceptions
	UnhandledException += (object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) =>
	{
		e.Handled = true;
		AppUnhandledException(e.Exception);
	};
	TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs e) => AppUnhandledException(e.Exception);

	sAppInstance = this;

	this.InitializeComponent();

	var thisInstance = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent();
	_appProcessID = thisInstance.ProcessId;

	// Get command-line arguments
	_commandLineArgs = Environment.GetCommandLineArgs();
	_commandLineArgsStr = Environment.CommandLine;

	// Initialize DispatcherQueueHelper (will be reinitialized when the UI must be opened and MainWindow is constructed)
	_dispatcherQueue = DispatcherQueueHelper.Initialize(DispatcherQueue.GetForCurrentThread());

	// Register OnProcessExit handler in order to deregister notificationManager when the app closes
	AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);

}

public static DispatcherQueue Initialize(DispatcherQueue dispatcherQueue)
{
	sDispatcherQueue = dispatcherQueue;
	return sDispatcherQueue;
}


void EnableAppCenter()
{
	AppCenter.LogLevel = LogLevel.Error;
	AppCenter.Start("<My app secret>", typeof(Analytics), typeof(Crashes));
}

void AppUnhandledException(Exception ex)
{
	Package package = Package.Current;
	PackageId packageId = package.Id;
	PackageVersion version = packageId.Version;
	var thisVersion = $"{version.Major}.{version.Minor}.{version.Build}";

	StringBuilder formattedException = new StringBuilder() { Capacity = 1000 };
	formattedException.Append($"UNHANDLED EXCEPTION (v{thisVersion})");
	if (ex is not null)
	{
		formattedException.Append($"\n>>>> HRESULT: {ex.HResult}\n");
		if (ex.Message is not null)
		{
			formattedException.Append("\n--- MESSAGE ---");
			formattedException.Append(ex.Message);
		}
		if (ex.StackTrace is not null)
		{
			formattedException.Append("\n--- STACKTRACE ---");
			formattedException.Append(ex.StackTrace);
		}
		if (ex.Source is not null)
		{
			formattedException.Append("\n--- SOURCE ---");
			formattedException.Append(ex.Source);
		}
		if (ex.InnerException is not null)
		{
			formattedException.Append("\n--- INNER ---");
			formattedException.Append(ex.InnerException);
		}
	}
	else
	{
		formattedException.Append("\nException is null!\n");
	}
	formattedException.Append("---");
	var largeString = formattedException.ToString();
	//ConditionalFileLogger.Log(largeString);
	// Report to AppCenter
	ReportLargeStringAsCrash(largeString);
}


public void ReportLargeStringAsCrash(string largeString)
{
	const int chunkSize = 125;  // Adjusted size limit per string property

	// Split the string into chunks
	var stringParts = SplitStringIntoChunks(largeString, chunkSize);

	// Create a dictionary to hold the chunks
	var errorProperties = new Dictionary<string, string>();

	for (int i = 0; i < stringParts.Count; i++)
	{
		// Add each chunk to the error properties dictionary
		errorProperties.Add($"c{i + 1}", stringParts[i]);
	}

	// Track non-fatal error with string chunks as properties
	Crashes.TrackError(new Exception("InApp exception"), errorProperties);
}


private List<string> SplitStringIntoChunks(string str, int chunkSize)
{
	var result = new List<string>();
	for (int i = 0; i < str.Length; i += chunkSize)
	{
		result.Add(str.Substring(i, Math.Min(chunkSize, str.Length - i)));
	}
	return result;
}

As I mentioned earlier, MS App Center doesn't show any exception that occured while still being in the App's constructor. It does show a couple of exceptions that occur in the OnLaunched method which indicate that for some users registration with the AppNotificationManager fails. The code for that is:

// Register the app with the AppNotificationManager in order to handle 'open-app' notification requests that
// occur while the app is already open.
_notificationManager = AppNotificationManager.Default;
// To ensure all Notification handling happens in this process instance, register for
// NotificationInvoked before calling Register(). Without this a new process will
// be launched to handle the notification.
_notificationManager.NotificationInvoked += OnNotificationInvoked;
_notificationManager.Register();

Reporting of exception in AppUnhandledException therefore seems to work well.

Copy link
Contributor

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 7 days of this comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) needs-author-feedback no-recent-activity
Projects
None yet
Development

No branches or pull requests

4 participants