[QuickAccess] Suppress unhandled XAML exceptions in flyout host#48457
Open
crutkas wants to merge 2 commits into
Open
[QuickAccess] Suppress unhandled XAML exceptions in flyout host#48457crutkas wants to merge 2 commits into
crutkas wants to merge 2 commits into
Conversation
PowerToys.QuickAccess.exe has no Application.UnhandledException handler and no Frame.NavigationFailed handler, so any throw during MainWindow construction or page navigation bubbles into the Windows App SDK launch path and FailFasts the process. - App.xaml.cs: hook Application.UnhandledException (log + set Handled=true) and wrap OnLaunched in a try/catch that logs the failure and calls Exit() if MainWindow cannot be constructed. - ShellPage.xaml.cs: hook ContentFrame.NavigationFailed (log + set Handled=true) so a LaunchPage or AppsListPage constructor failure no longer takes down the launcher. Both patterns mirror the existing Settings.UI handlers (App.xaml.cs:96, ShellViewModel.cs:86) and use the same ManagedCommon.Logger sink. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CS0104 ambiguity between Microsoft.UI.Xaml.UnhandledExceptionEventArgs and System.UnhandledExceptionEventArgs (both in scope via the using directives). Matches the Settings.UI App.xaml.cs:106 convention. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the two missing top-level exception handlers in the QuickAccess (Preview) flyout host so that an unhandled XAML exception during launch or page navigation no longer FailFasts
PowerToys.QuickAccess.exe.Spotted while reading through
App.OnLaunchedandShellPagefor an unrelated review of the flyout startup path — none of the existing handlers exist yet, so any throw duringMainWindowconstruction,ShellHost.Initialize, orContentFrame.Navigate(typeof(LaunchPage) | typeof(AppsListPage), …)bubbles all the way out to the Windows App SDK runtime and is stowed as a XAML failure. Compare withsrc\settings-ui\Settings.UI\SettingsXAML\App.xaml.cs, which already wiresUnhandledException += App_UnhandledException.Changes
src\settings-ui\QuickAccess.UI\QuickAccessXAML\App.xaml.csApplication.UnhandledExceptionin the constructor. The handler logs the exception viaManagedCommon.Logger.LogError(same logger Settings uses) and setse.Handled = true. QuickAccess is a transient launcher flyout owned by the runner, so swallowing a stray XAML error and keeping the host alive for the next summon is the correct trade-off — the failure is still recorded for diagnostics.OnLaunchedin a try/catch. IfMainWindow(which sets up window chrome, listener threads, the IPC coordinator, and the XAML shell) fails to construct, log the exception and callExit()cleanly rather than letting the throw escape into the Windows App SDK launch path.src\settings-ui\QuickAccess.UI\QuickAccessXAML\Flyout\ShellPage.xaml.csContentFrame.NavigationFailedafterInitializeComponent. A page constructor or XAML-load failure inLaunchPage/AppsListPagewould otherwise bubble out of theFrameand crash the launcher. The handler logs the failure (SourcePageType.FullName+ the exception) and marks it handled so the next summon retries navigation.No production behaviour changes when things work — only the failure paths are different. No public API surface changes.
Why both handlers, not just one
Application.UnhandledExceptiondoes not fire forFrame.NavigationFailed. The Frame raises its own event first and, if no handler runs ore.Handledis leftfalse, then it rethrows on the dispatcher.Frame.NavigationFailedonly fires for navigation failures — not for an exception thrown directly inOnLaunchedbefore any navigation happens.The two events are complementary, so both need a handler to fully cover the launch + navigation paths.
Testing
Microsoft.NETCore.App.Runtime.win-x64 = 10.0.9(the feed only has11.0.0-preview.1.26104.118), which fails the project restore for every WinUI project including this one. That's the same environment issue I called out on [Settings] Add navigation smoke test using winapp CLI (no WinAppDriver) #48414 — pipeline restore uses a different feed and is fine.Settings.UI(App.xaml.cs:96, 106-109,ShellViewModel.cs:86, 136), so namespace and signature drift risk is minimal. The only behavioural difference ise.Handled = true, which is the actual goal of this PR.Risk
Logger.LogErrorso the user can still find the trace in%LOCALAPPDATA%\Microsoft\PowerToys\Logs\.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
ADO: https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/61258633/