Skip to content

Conversation

@Jack251970
Copy link
Member

Updated the ErrorReporting class to log recoverable DWM composition exceptions instead of displaying the "Report problem UI," addressing issues with crashes in
PresentationFramework.dll. Introduced a new ExceptionHelper class to encapsulate logic for identifying recoverable DWM composition exceptions based on specific HRESULT values and stack trace patterns. Added detailed comments for context and referenced a related GitHub issue. Improved modularity and maintainability by isolating exception handling logic in the ExceptionHelper class.

From: microsoft/PowerToys#42588.
Resolve: #4016

Updated the `ErrorReporting` class to log recoverable DWM
composition exceptions instead of displaying the "Report
problem UI," addressing issues with crashes in
`PresentationFramework.dll`. Introduced a new `ExceptionHelper`
class to encapsulate logic for identifying recoverable DWM
composition exceptions based on specific HRESULT values and
stack trace patterns. Added detailed comments for context and
referenced a related GitHub issue. Improved modularity and
maintainability by isolating exception handling logic in the
`ExceptionHelper` class.
@github-actions github-actions bot added this to the 2.1.0 milestone Nov 16, 2025
@Jack251970 Jack251970 requested a review from Copilot November 16, 2025 03:40
@Jack251970 Jack251970 added the bug Something isn't working label Nov 16, 2025
@gitstream-cm
Copy link

gitstream-cm bot commented Nov 16, 2025

🥷 Code experts: Yusyuriv

Jack251970 has most 👩‍💻 activity in the files.
Yusyuriv, Jack251970 have most 🧠 knowledge in the files.

See details

Flow.Launcher/Helper/ErrorReporting.cs

Activity based on git-commit:

Jack251970
NOV
OCT
SEP
AUG
JUL
JUN 7 additions & 5 deletions

Knowledge based on git-blame:
Yusyuriv: 57%
Jack251970: 29%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

@gitstream-cm
Copy link

gitstream-cm bot commented Nov 16, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@Jack251970 Jack251970 enabled auto-merge November 16, 2025 03:42
Copilot finished reviewing on behalf of Jack251970 November 16, 2025 03:43
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 16, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds detection for recoverable DWM (Desktop Window Manager) composition COMExceptions and skips showing the ReportWindow for those cases; introduces a new helper to identify such exceptions and updates ErrorReporting to use it.

Changes

Cohort / File(s) Change Summary
DWM Composition Exception Detection
Flow.Launcher/Helper/ExceptionHelper.cs
New internal static class ExceptionHelper with IsRecoverableDwmCompositionException(Exception) that checks for COMException HRESULTs (DWM_E_COMPOSITIONDISABLED, STATUS_MESSAGE_LOST_HR), specific exception Source, and stack-trace mention of DwmCompositionChanged.
Error reporting conditional skip
Flow.Launcher/Helper/ErrorReporting.cs
After logging a fatal exception, conditionally returns early (skips creating/showing ReportWindow) when ExceptionHelper.IsRecoverableDwmCompositionException(e) is true; added explanatory comments.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant ErrorReporting
    participant ExceptionHelper
    participant ReportWindow

    App->>ErrorReporting: Exception occurs
    Note over ErrorReporting: Log fatal exception
    ErrorReporting->>ExceptionHelper: IsRecoverableDwmCompositionException(e)?
    alt Recoverable DWM Exception
        ExceptionHelper-->>ErrorReporting: true
        Note over ErrorReporting: Return early — skip ReportWindow
    else Non-recoverable Exception
        ExceptionHelper-->>ErrorReporting: false
        ErrorReporting->>ReportWindow: Create & Show error report UI
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Focused changes in two files with small, well-contained logic.
  • Review attention suggested for:
    • Correctness of HRESULT constants and their numeric values.
    • Robustness of stack-trace string check (case/format assumptions).
    • Appropriate internal visibility and unit-testability of the new helper.

Possibly related PRs

Possibly related issues

Suggested reviewers

  • jjw24
  • taooceros

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: handling recoverable DWM composition exceptions gracefully, which directly matches the core objective of the changeset.
Description check ✅ Passed The description is directly related to the changeset, detailing the ErrorReporting and ExceptionHelper changes, their purpose, and referencing the relevant GitHub issue and PR number.
Linked Issues check ✅ Passed The PR successfully addresses #4016 by implementing logic to identify and handle recoverable DWM composition exceptions gracefully instead of crashing, matching the issue's core requirement.
Out of Scope Changes check ✅ Passed All changes are focused and in-scope: modifications to ErrorReporting for conditional exception handling and addition of ExceptionHelper class to identify recoverable DWM exceptions, both directly addressing the linked issue.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve_dwm

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b44e525 and 8f83c10.

📒 Files selected for processing (2)
  • Flow.Launcher/Helper/ErrorReporting.cs (1 hunks)
  • Flow.Launcher/Helper/ExceptionHelper.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.
📚 Learning: 2025-07-06T12:21:37.947Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.

Applied to files:

  • Flow.Launcher/Helper/ExceptionHelper.cs
  • Flow.Launcher/Helper/ErrorReporting.cs
📚 Learning: 2025-06-29T08:31:07.816Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/Helper/PluginInstallationHelper.cs:251-252
Timestamp: 2025-06-29T08:31:07.816Z
Learning: In Flow Launcher's PluginInstallationHelper, when the progress box encounters an exception during download (indicated by reportProgress becoming null), the retry logic intentionally downloads without a progress handler to avoid repeating the same progress reporting failure. This prevents cascading exceptions in the progress reporting mechanism.

Applied to files:

  • Flow.Launcher/Helper/ErrorReporting.cs
📚 Learning: 2025-06-08T14:12:21.348Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3672
File: Flow.Launcher/MainWindow.xaml.cs:244-247
Timestamp: 2025-06-08T14:12:21.348Z
Learning: In Flow.Launcher, App.NotifyIcon is created before MainWindow creation, so null checks for App.NotifyIcon are not necessary when accessing it from MainWindow code.

Applied to files:

  • Flow.Launcher/Helper/ErrorReporting.cs
🧬 Code graph analysis (1)
Flow.Launcher/Helper/ErrorReporting.cs (1)
Flow.Launcher/Helper/ExceptionHelper.cs (2)
  • ExceptionHelper (10-44)
  • IsRecoverableDwmCompositionException (22-43)
🪛 GitHub Check: Check Spelling
Flow.Launcher/Helper/ExceptionHelper.cs

[warning] 42-42:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 22-22:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 42-42:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 22-22:
Dwm is not a recognized word. (unrecognized-spelling)

Flow.Launcher/Helper/ErrorReporting.cs

[warning] 25-25:
Dwm is not a recognized word. (unrecognized-spelling)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (4)
Flow.Launcher/Helper/ErrorReporting.cs (1)

19-26: LGTM! Proper handling of recoverable DWM composition exceptions.

The early return for recoverable DWM composition exceptions is correctly placed after logging but before showing the ReportWindow. The detailed comments provide excellent context about the issue origin and rationale. This approach aligns with graceful degradation patterns for transient WPF/DWM composition failures.

Flow.Launcher/Helper/ExceptionHelper.cs (3)

1-3: Verify copyright header appropriateness.

This file includes a Microsoft copyright header, but it's a new file in the Flow Launcher repository. While the PR mentions the code is "derived from or inspired by" PowerToys PR #42588, a new file should typically carry the Flow Launcher or contributor's copyright. If portions are directly adapted from PowerToys, consider adding an attribution comment instead while using Flow Launcher's standard copyright header.

Please verify whether this copyright header is appropriate, or if it should be replaced with Flow Launcher's standard header with an attribution comment.


12-17: LGTM! Constants are well-defined.

The HRESULT constants are correctly defined with unchecked() to handle negative values, and the comment explaining the STATUS_MESSAGE_LOST_HR calculation is helpful.


39-42: LGTM! Stack trace fallback with case-insensitive matching.

The fallback check for "DwmCompositionChanged" in the stack trace with StringComparison.OrdinalIgnoreCase is a reasonable last-resort heuristic to catch recoverable DWM composition exceptions that may not have the expected HRESULT values.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
Flow.Launcher/Helper/ErrorReporting.cs (1)

20-25: DWM guard behavior looks right; consider simplifying the helper call.

The new guard correctly keeps logging while suppressing the report UI for recoverable DWM composition COMExceptions, which aligns with the PR goal. One small readability tweak:

  • ExceptionHelper.IsRecoverableDwmCompositionException already handles non‑COM exceptions internally via pattern matching, so the explicit as COMException cast is redundant and slightly narrows future flexibility (e.g., if you later want to inspect wrapper exceptions inside the helper).

You could simplify to:

-        if (ExceptionHelper.IsRecoverableDwmCompositionException(e as System.Runtime.InteropServices.COMException)) return;
+        if (ExceptionHelper.IsRecoverableDwmCompositionException(e))
+        {
+            return;
+        }

This preserves behavior today and keeps the helper usage straightforward.

Flow.Launcher/Helper/ExceptionHelper.cs (1)

1-44: Helper logic matches the described DWM COMException patterns; consider tests and possible inner‑exception handling.

The detection logic for recoverable DWM composition exceptions looks solid: you constrain on COMException, check the two specific HRESULTs, gate one on Source == "PresentationFramework", and fall back to the DwmCompositionChanged stack‑trace pattern. That matches the linked issue and the intent to avoid raising the report UI for these crashes.

Two small, non‑blocking improvements you might want to consider:

  1. Unit tests for the helper branches

    Creating targeted tests for:

    • DWM_E_COMPOSITIONDISABLED
    • STATUS_MESSAGE_LOST_HR + PresentationFramework source
    • Stack‑trace pattern only
    • Non‑matching COMException and non‑COM exceptions

    would help prevent regressions if more patterns or HRESULTs are added later.

  2. Future‑proofing for wrapped exceptions (optional)

    Right now, only top‑level COMExceptions are treated as recoverable. If WPF or other infrastructure ever starts wrapping these in another exception type (e.g., XamlParseException with an inner COMException), you may want to extend this helper to optionally walk InnerException/AggregateException trees. Not necessary for the current bug, but something to keep in mind.

Overall, the implementation is clear and localized, which should make future tuning straightforward.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6c4132 and b44e525.

📒 Files selected for processing (2)
  • Flow.Launcher/Helper/ErrorReporting.cs (1 hunks)
  • Flow.Launcher/Helper/ExceptionHelper.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/Helper/PluginInstallationHelper.cs:251-252
Timestamp: 2025-06-29T08:31:07.816Z
Learning: In Flow Launcher's PluginInstallationHelper, when the progress box encounters an exception during download (indicated by reportProgress becoming null), the retry logic intentionally downloads without a progress handler to avoid repeating the same progress reporting failure. This prevents cascading exceptions in the progress reporting mechanism.
📚 Learning: 2025-07-06T12:21:37.947Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.

Applied to files:

  • Flow.Launcher/Helper/ExceptionHelper.cs
  • Flow.Launcher/Helper/ErrorReporting.cs
📚 Learning: 2025-06-29T08:31:07.816Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/Helper/PluginInstallationHelper.cs:251-252
Timestamp: 2025-06-29T08:31:07.816Z
Learning: In Flow Launcher's PluginInstallationHelper, when the progress box encounters an exception during download (indicated by reportProgress becoming null), the retry logic intentionally downloads without a progress handler to avoid repeating the same progress reporting failure. This prevents cascading exceptions in the progress reporting mechanism.

Applied to files:

  • Flow.Launcher/Helper/ErrorReporting.cs
📚 Learning: 2025-06-08T14:12:21.348Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3672
File: Flow.Launcher/MainWindow.xaml.cs:244-247
Timestamp: 2025-06-08T14:12:21.348Z
Learning: In Flow.Launcher, App.NotifyIcon is created before MainWindow creation, so null checks for App.NotifyIcon are not necessary when accessing it from MainWindow code.

Applied to files:

  • Flow.Launcher/Helper/ErrorReporting.cs
🧬 Code graph analysis (1)
Flow.Launcher/Helper/ErrorReporting.cs (1)
Flow.Launcher/Helper/ExceptionHelper.cs (2)
  • ExceptionHelper (10-44)
  • IsRecoverableDwmCompositionException (22-43)
🪛 GitHub Check: Check Spelling
Flow.Launcher/Helper/ExceptionHelper.cs

[warning] 42-42:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 22-22:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 42-42:
Dwm is not a recognized word. (unrecognized-spelling)


[warning] 22-22:
Dwm is not a recognized word. (unrecognized-spelling)

Flow.Launcher/Helper/ErrorReporting.cs

[warning] 25-25:
Dwm is not a recognized word. (unrecognized-spelling)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL analysis (csharp)
  • GitHub Check: Agent
  • GitHub Check: gitStream.cm
  • GitHub Check: build

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves error handling for WPF DWM composition exceptions by introducing graceful recovery instead of displaying error UI. The changes isolate exception detection logic in a new ExceptionHelper class and update ErrorReporting to silently log recoverable DWM composition exceptions.

  • Introduced ExceptionHelper class with logic to identify recoverable DWM composition exceptions based on HRESULT values (0x80263001, 0xD0000701) and stack trace patterns
  • Modified ErrorReporting.Report() to check for recoverable DWM exceptions before displaying error UI
  • Added detailed comments explaining the issue context and linking to the WPF source code where these exceptions originate

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
Flow.Launcher/Helper/ExceptionHelper.cs New class providing static method to identify recoverable DWM composition COMExceptions by checking HRESULT codes and stack traces
Flow.Launcher/Helper/ErrorReporting.cs Updated to check for recoverable DWM exceptions and silently log them instead of showing error dialog, preventing UI hangs during WPF composition changes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

5 min review bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: COMException- Desktop composition is disabled

2 participants