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

VisualStateManager throws generic unhelpful exception when a Setter contains an Invalid Element Name #5575

Open
michael-hawker opened this issue Jul 28, 2021 · 7 comments
Labels
area-ErrorHandling Issues related to error reporting and debugging area-VSM area-XamlCompiler bug Something isn't working needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) product-winui3 WinUI 3 issues team-Markup Issue for the Markup team wct

Comments

@michael-hawker
Copy link
Collaborator

Describe the bug
Trying to override the NavigationView style is causing a crash in OnApplyTemplate when we move the VisualStateManager to its proper location.

Steps to reproduce the bug

  1. https://github.com/michael-hawker/UWPCommunityToolkit/tree/onapplytemplate_crash
  2. Run Toolkit Sample App
  3. Open on TabbedCommandBar sample

Expected behavior
Not crash or coherent error message.

Version Info

NuGet package version: WinUI 2.6.1

Windows app type:

UWP Win32
Yes
Windows version Saw the problem?
21H1 (19043) Yes
October 2020 Update (19042)
May 2020 Update (19041)
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop
Xbox
Surface Hub
IoT

Additional context
Our template is about 80% the same as the inbox NavigationView, we have another Grid around the whole template, which I realized we hadn't moved our VSM up into (as the VSM wasn't firing). When moving the VSM up into the top-level Grid, it crashes. If you remove the VSM, it doesn't crash (but also doesn't behave as expected).

Stack Trace:

Exception thrown at 0x00007FFDE1D04ED9 in Microsoft.Toolkit.Uwp.SampleApp.exe: Microsoft C++ exception: winrt::hresult_error at memory location 0x000000FF3DAFB2F0.
>	Microsoft.Toolkit.Uwp.UI.Controls.Core.dll!Microsoft.Toolkit.Uwp.UI.Controls.TabbedCommandBar.OnApplyTemplate() Line 49	C#
 	[Native to Managed Transition]	
 	Windows.UI.Xaml.dll!DirectUI::FrameworkElementGenerated::OnApplyTemplateProtected() Line 1096	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkElement::OnApplyTemplateFromCore(CFrameworkElement * nativeTarget) Line 191	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::FrameworkElement_OnApplyTemplate(CFrameworkElement *) Line 850	C++
 	Windows.UI.Xaml.dll!CFrameworkElement::InvokeApplyTemplate(unsigned char * bAddedVisuals) Line 1289	C++
 	Windows.UI.Xaml.dll!CFrameworkElement::MeasureCore(XSIZEF availableSize, XSIZEF & desiredSize) Line 1561	C++
 	Windows.UI.Xaml.dll!CUIElement::MeasureInternal(XSIZEF availableSize) Line 4121	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 3981	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CGrid::MeasureCell(CUIElement * const rowHeightTypes, const CellUnitTypes columnWidthTypes, const CellUnitTypes) Line 479	C++
 	Windows.UI.Xaml.dll!CGrid::MeasureCellsGroup(unsigned int cellsHead, unsigned int cellCount, const float rowSpacing, const float columnSpacing, const bool ignoreColumnDesiredSize, const bool forceRowToInfinity, Jupiter::stack_vector<CellCache,16> & cellCacheVector) Line 359	C++
 	Windows.UI.Xaml.dll!CGrid::MeasureOverride(XSIZEF availableSize, XSIZEF & desiredSize) Line 1219	C++
 	Windows.UI.Xaml.dll!CFrameworkElement::MeasureCore(XSIZEF availableSize, XSIZEF & desiredSize) Line 1614	C++
 	Windows.UI.Xaml.dll!CUIElement::MeasureInternal(XSIZEF availableSize) Line 4121	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 3981	C++
 	[Inline Frame] Windows.UI.Xaml.dll!UIElement_Measure(CUIElement *) Line 999	C++
 	Windows.UI.Xaml.dll!DirectUI::UIElement::MeasureImpl(Windows::Foundation::Size availableSize) Line 573	C++
 	Windows.UI.Xaml.dll!DirectUI::UIElementGenerated::Measure(Windows::Foundation::Size availableSize) Line 4318	C++
 	Windows.UI.Xaml.dll!DirectUI::Page::MeasureOverride(Windows::Foundation::Size availableSize, Windows::Foundation::Size * pReturnValue) Line 628	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkElementGenerated::MeasureOverrideProtected(Windows::Foundation::Size availableSize, Windows::Foundation::Size * pReturnValue) Line 1056	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkElement::MeasureOverrideFromCore(CFrameworkElement * nativeTarget, float inWidth, float inHeight, float * outWidth, float * outHeight) Line 255	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::FrameworkElement_MeasureOverride(CFrameworkElement *) Line 844	C++
 	Windows.UI.Xaml.dll!CFrameworkElement::MeasureCore(XSIZEF availableSize, XSIZEF & desiredSize) Line 1597	C++
 	Windows.UI.Xaml.dll!CUIElement::MeasureInternal(XSIZEF availableSize) Line 4121	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 3981	C++
 	Windows.UI.Xaml.dll!CContentPresenter::MeasureOverride(XSIZEF availableSize, XSIZEF & desiredSize) Line 845	C++
 	Windows.UI.Xaml.dll!CFrameworkElement::MeasureCore(XSIZEF availableSize, XSIZEF & desiredSize) Line 1614	C++
 	Windows.UI.Xaml.dll!CUIElement::MeasureInternal(XSIZEF availableSize) Line 4121	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 3981	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CUIElement::Measure(XSIZEF availableSize) Line 4031	C++
 	Windows.UI.Xaml.dll!CLayoutManager::UpdateLayout(unsigned int controlWidth, unsigned int controlHeight) Line 279	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CLayoutManager::UpdateLayout() Line 226	C++
 	Windows.UI.Xaml.dll!CUIElement::UpdateLayout() Line 3729	C++
 	Windows.UI.Xaml.dll!CUIElement::BoundsTestEntry<XPOINTF>(const HitTestParams & hitTestParams, const XPOINTF & target, CBoundedHitTestVisitor * pCallback, bool canHitDisabledElements, bool canHitInvisibleElements) Line 15243	C++
 	Windows.UI.Xaml.dll!CUIElement::HitTestEntry(const HitTestParams & hitTestParams, XPOINTF hitPoint, bool canHitMultipleElements, bool canHitDisabledElements, bool canHitInvisibleElements, CHitTestResults * pHitElements) Line 2456	C++
 	Windows.UI.Xaml.dll!CUIElement::HitTestEntry(const HitTestParams & hitTestParams, XPOINTF hitPoint, bool canHitDisabledElements, bool ppHitElement, CUIElement * *) Line 2430	C++
 	Windows.UI.Xaml.dll!CCoreServices::HitTest(XPOINTF ptHit, CDependencyObject * pHitTestRoot, CDependencyObject * * ppVisualHit, bool hitDisabledElement) Line 4646	C++
 	Windows.UI.Xaml.dll!ContentRootInput::PointerInputProcessor::HitTestHelper(XPOINTF ptHit, CDependencyObject * pHitTestRoot, CDependencyObject * * ppVisualHit) Line 1043	C++
 	Windows.UI.Xaml.dll!ContentRootInput::PointerInputProcessor::HitTestWithLightDismissAwareness(xref_ptr<CDependencyObject> & contactDO, XPOINTF contactPoint, MessageMap message, PointerInfo * pointerInfo, CDependencyObject * hitTestRoot) Line 1085	C++
 	Windows.UI.Xaml.dll!ContentRootInput::PointerInputProcessor::ProcessPointerInput(InputMessage * pMsg, int * handled) Line 263	C++
 	Windows.UI.Xaml.dll!CInputServices::ProcessInput(InputMessage * pMsg, CContentRoot * contentRoot, int * handled) Line 888	C++
 	Windows.UI.Xaml.dll!CCoreServices::ProcessInput(InputMessage * pMessage, CContentRoot * contentRoot, int * fHandled) Line 992	C++
 	Windows.UI.Xaml.dll!CXcpBrowserHost::ReplayPreviousPointerUpdate(unsigned int previousPointerUpdateMsgId) Line 1893	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::OnWindowMessage(HWND__ * msg, unsigned int wParam, unsigned __int64 lParam, __int64) Line 1178	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::ProcessMessage(HWND__ *) Line 911	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::WindowProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 842	C++
 	Windows.UI.Xaml.dll!CDeferredInvoke::DispatchQueuedMessage(bool * dispatchedWork, bool * hasMoreWork) Line 301	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::MessageTimerCallback() Line 1534	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::MessageTimerCallbackStatic(void * myUserData) Line 1526	C++
 	CoreMessaging.dll!00007ffddf1f53db()	Unknown
 	CoreMessaging.dll!00007ffddf21c85b()	Unknown
 	CoreMessaging.dll!00007ffddf1f996b()	Unknown
 	CoreMessaging.dll!00007ffddf1f8e26()	Unknown
 	CoreMessaging.dll!00007ffddf1f7061()	Unknown
 	CoreMessaging.dll!00007ffddf1f6e83()	Unknown
 	user32.dll!00007ffde2d0e858()	Unknown
 	user32.dll!00007ffde2d0e3dc()	Unknown
 	user32.dll!00007ffde2d20bc3()	Unknown
 	ntdll.dll!00007ffde4630c54()	Unknown
 	win32u.dll!00007ffde2401064()	Unknown
 	user32.dll!00007ffde2d0a5c3()	Unknown
 	user32.dll!00007ffde2d0a523()	Unknown
 	Windows.UI.dll!00007ffdd1cba8ae()	Unknown
 	Windows.UI.dll!00007ffdd1cba680()	Unknown
 	Windows.UI.dll!00007ffdd1cba50b()	Unknown
 	Windows.UI.Xaml.dll!CJupiterWindow::RunCoreWindowMessageLoop() Line 1234	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CJupiterControl::RunMessageLoop() Line 1065	C++
 	Windows.UI.Xaml.dll!DirectUI::DXamlCore::RunMessageLoop() Line 2463	C++
 	twinapi.appcore.dll!00007ffddc8a5eca()	Unknown
 	twinapi.appcore.dll!00007ffddc85e65f()	Unknown
 	SHCore.dll!00007ffde42be449()	Unknown
 	kernel32.dll!00007ffde2eb7034()	Unknown
 	ntdll.dll!00007ffde45e2651()	Unknown
@michael-hawker
Copy link
Collaborator Author

Tried moving the VSM to the very top before the Grid.RowDefinitions as well just in case, but same issue.

@michael-hawker
Copy link
Collaborator Author

I even simplified the VSM to this and still received the crash:

                         <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="AutoSuggestGroup">
                                <VisualState x:Name="AutoSuggestBoxVisible" />
                                <VisualState x:Name="AutoSuggestBoxCollapsed">
                                    <VisualState.Setters>
                                        <Setter Target="AutoSuggestArea.Visibility" Value="Collapsed" />
                                        <Setter Target="TopPaneAutoSuggestArea.Visibility" Value="Collapsed" />
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="BackButtonGroup">
                                <VisualState x:Name="BackButtonVisible">
                                    <VisualState.Setters>
                                        <Setter Target="BackButtonPlaceholderOnTopNav.Width" Value="{ThemeResource NavigationBackButtonWidth}" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="BackButtonCollapsed" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

@michael-hawker
Copy link
Collaborator Author

michael-hawker commented Jul 28, 2021

Been fiddling and got a slightly different stack, loaded the Microsoft.UI.Xaml symbols and saw this:

 	KernelBase.dll!RaiseException�()	Unknown
 	vcruntime140_app.dll!00007ffdd1556220()	Unknown
 	Microsoft.UI.Xaml.dll!winrt::throw_hresult(const winrt::hresult result) Line 4892	C++
 	[Inline Frame] Microsoft.UI.Xaml.dll!winrt::check_hresult(const winrt::hresult) Line 4962	C++
 	[Inline Frame] Microsoft.UI.Xaml.dll!winrt::impl::consume_Windows_UI_Xaml_IVisualStateManagerStatics<winrt::Windows::UI::Xaml::IVisualStateManagerStatics>::GoToState(const winrt::Windows::UI::Xaml::Controls::Control & control, const winrt::param::hstring & stateName, bool useTransitions) Line 4324	C++
 	[Inline Frame] Microsoft.UI.Xaml.dll!winrt::Windows::UI::Xaml::VisualStateManager::GoToState::__l2::<lambda_5fa6541ce9215f1e31f46d0a7bbb38d6>::operator()(const winrt::Windows::UI::Xaml::IVisualStateManagerStatics &) Line 13049	C++
 	Microsoft.UI.Xaml.dll!winrt::impl::call_factory<winrt::Windows::UI::Xaml::VisualStateManager,winrt::Windows::UI::Xaml::IVisualStateManagerStatics,<lambda_5fa6541ce9215f1e31f46d0a7bbb38d6>>(winrt::Windows::UI::Xaml::VisualStateManager::GoToState::__l2::<lambda_5fa6541ce9215f1e31f46d0a7bbb38d6> && callback) Line 6249	C++
 	[Inline Frame] Microsoft.UI.Xaml.dll!winrt::Windows::UI::Xaml::VisualStateManager::GoToState(const winrt::Windows::UI::Xaml::Controls::Control & useTransitions, const winrt::param::hstring &) Line 13049	C++
>	Microsoft.UI.Xaml.dll!NavigationView::UpdateVisualState(bool) Line 3354	C++
 	Microsoft.UI.Xaml.dll!NavigationView::OnApplyTemplate() Line 709	C++
 	Microsoft.UI.Xaml.dll!winrt::impl::produce<NavigationView,winrt::Windows::UI::Xaml::IFrameworkElementOverrides>::OnApplyTemplate() Line 7699	C++
 	[Managed to Native Transition]	
 	Microsoft.Toolkit.Uwp.UI.Controls.Core.dll!Microsoft.Toolkit.Uwp.UI.Controls.TabbedCommandBar.OnApplyTemplate() Line 49	C#
 	[Native to Managed Transition]	
 	Windows.UI.Xaml.dll!DirectUI::FrameworkElementGenerated::OnApplyTemplateProtected() Line 1096	C++

At least this stack is getting me farther as it's pointing to this function:

Though I don't see that function calling a visual state:

void NavigationView::UpdatePaneTitleMargins()
{
if (ShouldPreserveNavigationViewRS4Behavior())
{
if (auto paneTitleFrameworkElement = m_paneTitleFrameworkElement.get())
{
double width = GetPaneToggleButtonWidth();
if (ShouldShowBackButton() && IsOverlay())
{
width += c_backButtonWidth;
}
paneTitleFrameworkElement.Margin({ width, 0, 0, 0 }); // see "Hamburger title" on uni
}
}
}

The other line called out is here:

winrt::VisualStateManager::GoToState(*this, box ? L"AutoSuggestBoxVisible" : L"AutoSuggestBoxCollapsed", false /*useTransitions*/);

Which at least seems more useful. I tried removing that Visual State and then it was able to load. I can still add an AutoSuggestBox, so I'm not sure what this Visual State actually does... 🤔

Still no idea why this particular VisualState was causing a crash. Maybe because we didn't have a AutoSuggestArea element defined?

Yup removing that line of the VisualState caused it not to crash. So something about having a pointer in the Setter of a Visual State to an undefined element is causing this to crash internally with a super unhelpful error message compared to saying something like:

Invalid VisualState Setter. Can't find element 'AutoSuggestArea' for 'AutoSuggestBoxCollapsed' state in 'TabbedCommandBar'

@StephenLPeters
Copy link
Contributor

Yeah, Setter's will compile even if their targets are not defined, but when they are executed they will have a runtime crash. It would be great if the error message that was raised was more reasonable though. @RealTommyKlein could this error message be improved from the xaml compiler side?

@michael-hawker sounds like you found the cause of your issue, maybe we can rename this issue to be about making the error message for this scenario better?

@StephenLPeters StephenLPeters added needs-author-feedback Asked author to supply more information. and removed needs-triage Issue needs to be triaged by the area owners labels Jul 28, 2021
@michael-hawker michael-hawker changed the title OnApplyTemplate Crash with no Error Message VisualStateManager throws generic unhelpful exception when a Setter contains an Invalid Element Name Jul 28, 2021
@michael-hawker
Copy link
Collaborator Author

@StephenLPeters done! This seems like something the Compiler or an Analyzer could be able to catch before runtime. But at least at runtime the error message should be more than 'Exception'! 🙂

@ghost ghost added needs-triage Issue needs to be triaged by the area owners and removed needs-author-feedback Asked author to supply more information. labels Jul 28, 2021
@StephenLPeters StephenLPeters added area-XamlCompiler needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) team-Markup Issue for the Markup team needs-triage Issue needs to be triaged by the area owners and removed needs-triage Issue needs to be triaged by the area owners labels Jul 29, 2021
@evelynwu-msft
Copy link
Contributor

We raise a stowed exception that contains a helpful error message, but breaking on those may not be turned on by default in VS. There's also slightly different behavior in this (and similar) error case depending on whether or not a debugger attached for historical reasons that we really should get rid of. I agree that overall it's a pretty meh experience.

@evelynwu-msft evelynwu-msft added bug Something isn't working and removed needs-triage Issue needs to be triaged by the area owners labels Jul 31, 2021
@evelynwu-msft evelynwu-msft self-assigned this Jul 31, 2021
@evelynwu-msft evelynwu-msft added area-ErrorHandling Issues related to error reporting and debugging area-VSM labels Oct 17, 2022
@evelynwu-msft evelynwu-msft removed their assignment Oct 17, 2022
@evelynwu-msft evelynwu-msft added the product-winui3 WinUI 3 issues label Oct 18, 2022
@michael-hawker
Copy link
Collaborator Author

Not sure if this was addressed any with the error handling improvements, would have to check latest. Bumping based on #8638

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-ErrorHandling Issues related to error reporting and debugging area-VSM area-XamlCompiler bug Something isn't working needs-winui-3 Indicates that feature can only be done in WinUI 3.0 or beyond. (needs winui 3) product-winui3 WinUI 3 issues team-Markup Issue for the Markup team wct
Projects
None yet
Development

No branches or pull requests

3 participants