Skip to content

Record Avalonia UI mode in crash reports - #1066

Open
johnml1135 wants to merge 3 commits into
mainfrom
avalonia-crash-reporting
Open

Record Avalonia UI mode in crash reports#1066
johnml1135 wants to merge 3 commits into
mainfrom
avalonia-crash-reporting

Conversation

@johnml1135

@johnml1135 johnml1135 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Crash reports now record whether Avalonia ("New") UI mode is active and
which tools are opted out via UIModeDisabledTools, alongside the OS/.NET
environment info ErrorReporter already collects. That value tracks the
whole session, not just the moment the window opened: toggling UI mode from
either Options dialog updates the crash-report property the same instant it
updates the PropertyTable.

The reviewer question this needs to answer up front is "is the recorded
value trustworthy, and does it stay that way?" The first version of this
branch seeded the value once at window construction and left it there for
the rest of the session -- review feedback flagged that a crash right after
an in-session Legacy<->New toggle would still show the stale startup mode.
This revision closes that gap rather than just labeling it: both Options
dialogs now push the same update into ErrorReporter that they already push
into the PropertyTable.

Where to look

  • FwXWindow.SeedUIModeProperties -- the startup seed; two
    ErrorReporter.AddProperty calls using the exact NormalizeUIMode output
    already written to the PropertyTable two lines above.
  • LexOptionsDlg.m_btnOK_Click (WinForms) and
    AvaloniaOptionsDialogLauncher.ApplyUiModeLive/ApplyDisabledToolsLive
    (Avalonia) -- both live-toggle paths now call ErrorReporter.AddProperty
    right alongside their existing PropertyTable broadcast.
  • ApplyUiModeLive/ApplyDisabledToolsLive moved from private to
    internal static so they are unit-tested directly, the same pattern
    FwXWindowUIModeSeedingTests already used for the seed path.
  • FwXWindowUIModeSeedingTests, LexOptionsDlgTests,
    AvaloniaOptionsDialogLauncherTests -- all assert directly against
    SIL.Reporting.ErrorReport.Properties, not just the PropertyTable.

Deliberately not here

  • LexOptionsDlg (WinForms) has no per-tool disabled-tools editor, so only
    AvaloniaUIMode needs a live update there; ApplyDisabledToolsLive exists
    only on the Avalonia side, where that setting is actually edited.

Standalone branch off main, not stacked. ./build.ps1 and the three
targeted test.ps1 runs above are clean on a fresh worktree (8 + 46 tests,
all passed). Full repo test.ps1 was not run.


Reading this a year from now -- start here

This PR is small enough that no research or working notes were produced or
deleted for it. The one thing worth knowing later: the crash-report value
was seed-only in the first version of this branch and was made live in
response to review feedback -- see "Decisions, and why" below.

Decisions, and why

Seed once, then keep it live, rather than accept staleness. The first
version of this branch recorded AvaloniaUIMode/AvaloniaDisabledTools
only in FwXWindow.SeedUIModeProperties, at window construction. That was a
deliberate first cut: seed-time coverage costs nothing extra (the value
already exists at that point), and most crashes happen without a mid-session
mode toggle. Review feedback pointed out the failure mode this leaves: a
crash immediately after toggling UI mode shows the mode active at startup,
not at crash time. Rather than rename the properties to admit the staleness
(...AtStartup), this revision wires the two places that already broadcast
a live toggle -- LexOptionsDlg.m_btnOK_Click and
AvaloniaOptionsDialogLauncher's apply path -- to also call
ErrorReporter.AddProperty, so the crash-report value is exactly as fresh
as the PropertyTable value it mirrors.

internal static, not private, for the two Avalonia apply helpers.
ApplyUiModeLive and the new ApplyDisabledToolsLive are internal static -- visible via InternalsVisibleTo, the same mechanism
NormalizeUiMode/ShouldApplyWritingSystemChange already use in this file
-- so AvaloniaOptionsDialogLauncherTests can exercise the crash-report
side effect directly, without standing up a full LcmCache/mediator/Apply
call.

Property names. AvaloniaUIMode and AvaloniaDisabledTools were picked
to read clearly in a raw crash-report text dump next to the existing flat
Key: value diagnostic lines (OSVersion, MachineName, etc.) -- not to
mirror the internal UIMode/UIModeDisabledTools PropertyTable key
names, which would be ambiguous out of context to a support engineer reading
a report without the surrounding code.

Evidence
  • ./build.ps1 succeeds on a fresh worktree off origin/main.
  • ./test.ps1 -TestProject "Src/xWorks/xWorksTests" -TestFilter "FwXWindowUIModeSeedingTests" -- Test Run Successful. Total tests: 8.
  • ./test.ps1 -TestProject "Src/LexText/LexTextControls/LexTextControlsTests" -TestFilter "LexOptionsDlgTests|AvaloniaOptionsDialogLauncherTests" --
    Test Run Successful. Total tests: 46, including the two new tests
    asserting ErrorReport.Properties["AvaloniaUIMode"] and
    ["AvaloniaDisabledTools"] after a live toggle.
  • OkClick_LeavesLegacyWhenUserDoesNotChangeSelection additionally asserts
    the crash-report property stays unset when the user does not change the
    mode, so an unrelated OK-click cannot fabricate a value.

This change is Reviewable

Add the persisted UIMode and UIModeDisabledTools values to the
ErrorReporter property bag alongside the other environment info,
so a crash report shows whether Avalonia UI was active and which
tools opted out, without duplicating anything the trace covers.
Assert that SeedUIModeProperties records AvaloniaUIMode and
AvaloniaDisabledTools on ErrorReporter, so a regression in that
wiring surfaces as a test failure instead of only in a real crash
report.
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown

NUnit Tests

    1 files  ±0      1 suites  ±0   10m 59s ⏱️ -36s
5 763 tests +3  5 682 ✅ +3  81 💤 ±0  0 ❌ ±0 
5 772 runs  +3  5 691 ✅ +3  81 💤 ±0  0 ❌ ±0 

Results for commit aa06e67. ± Comparison against base commit f2fac18.

♻️ This comment has been updated with latest results.

@codecov-commenter

codecov-commenter commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 38.05%. Comparing base (f2fac18) to head (aa06e67).

Files with missing lines Patch % Lines
...Controls/Avalonia/AvaloniaOptionsDialogLauncher.cs 90.90% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1066   +/-   ##
=======================================
  Coverage   38.04%   38.05%           
=======================================
  Files        1499     1499           
  Lines      350108   350114    +6     
  Branches    40231    40232    +1     
=======================================
+ Hits       133216   133238   +22     
+ Misses     187607   187593   -14     
+ Partials    29285    29283    -2     
Files with missing lines Coverage Δ
Src/LexText/LexTextControls/LexOptionsDlg.cs 43.21% <100.00%> (+0.15%) ⬆️
Src/xWorks/FwXWindow.cs 11.31% <100.00%> (+0.15%) ⬆️
...Controls/Avalonia/AvaloniaOptionsDialogLauncher.cs 45.18% <90.90%> (+5.92%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@papeh

papeh commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

As you mention, this records the values only at startup. This would be confusing if a value is changed. I think we should update the error report properties when the values change. If that is too much effort for this PR, I suggest renaming the error report properties to "...AtStartup" until the update is implemented.

I would find this PR easier to review if the description were more concise. I learned nothing by reading the second sentence, the second paragraph, and the "Where to look" section.

Addresses review feedback on PR #1066: AvaloniaUIMode and
AvaloniaDisabledTools only reflected the values seeded at window
construction, so a crash after an in-session UI-mode toggle showed the
stale startup values instead of what was active at crash time.

LexOptionsDlg.m_btnOK_Click and the new AvaloniaOptionsDialogLauncher
ApplyUiModeLive/ApplyDisabledToolsLive helpers now call
ErrorReporter.AddProperty alongside the existing PropertyTable
broadcast, so the crash-report value tracks every live change instead
of only the initial seed. Covered by new tests in LexOptionsDlgTests
and AvaloniaOptionsDialogLauncherTests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@johnml1135

Copy link
Copy Markdown
Contributor Author

Thanks -- both addressed in aa06e67:

  • Staleness: implemented the live update rather than renaming. LexOptionsDlg.m_btnOK_Click and the new AvaloniaOptionsDialogLauncher.ApplyUiModeLive/ApplyDisabledToolsLive helpers now call ErrorReporter.AddProperty alongside the existing PropertyTable broadcast, so the crash-report value tracks every live mode/disabled-tools change instead of only the window-construction seed. Covered by new tests in LexOptionsDlgTests and AvaloniaOptionsDialogLauncherTests.
  • Description length: rewrote the PR body to a plain Summary + Test plan, dropped the accordions and the "Where to look" walkthrough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants