Skip to content

Keep the restore error and stop the tool once when tray start-up fails - #26

Merged
matt-edmondson merged 2 commits into
mainfrom
fix-tray-start-sequence
Sep 29, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix-tray-start-sequence

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #12
Fixes #13

Both bugs are in TrayApplication's start sequence, and the triage on each said to fix them together, so they share this PR.

#12: a failed preference restore was hidden by a successful OnStart

TrayMenu.Run clears LastError on success. That wiped the restore error seeded by RunTray before the menu was ever painted. The start action now runs in a new TrayApplication.StartTool(), which puts the seeded error back when the start succeeds. A failed start still reports its own error.

#13: tray start-up that threw after OnStart started the tool twice

TrayApplication now records ToolStarted when the start action runs, separately from HasStarted:

  • Dispose stops the tool when ToolStarted is set. It used to check HasStarted, which is still false if start-up threw partway.
  • RunTray's catch has moved to TrayAppBuilder.RecoverFromTrayFailure so that it can be tested. When the tool has started but the tray has not finished starting, it disposes the host, which calls OnStop once. It then reports the error and exits 1, instead of printing "could not show a tray icon" and calling OnStart again from ConsoleRunner.

The README's "Load-bearing behaviour" table has a row for each.

Tests

Five new tests in TrayApplicationTests exercise StartTool and RecoverFromTrayFailure without a display. Three of them failed before the fix:

  • StartTool_WhenTheStartActionSucceeds_KeepsTheSeededRestoreError
  • Dispose_AfterTheToolStartedButBeforeTheTrayFinishedStarting_StopsTheTool
  • RecoverFromTrayFailure_AfterTheToolStarted_DoesNotStartItAgain (OnStart ran twice)

The other two check behaviour that must not change: a failed start reports its own error, and a refusal before start still falls back to the console. The full suite passes locally: 122 passed, 1 skipped because it is platform-conditional. The solution builds with 0 warnings.

Not done: the optional check that icon resources exist in Build(), which #13 suggested. With this change a mistyped icon name no longer double-starts the tool, so that check would be a separate improvement.

🤖 Generated with Claude Code

https://claude.ai/code/session_011tqaKZaJ9nxFMskVoZgreK


Generated by Claude Code

A successful OnStart cleared the preference-restore error seeded into the
menu, so the status line looked healthy although the remembered setting
was not applied. The start sequence now re-seeds it after a successful
start; a failed start still reports its own error.

When start-up threw after OnStart had run, RunTray saw HasStarted false,
skipped OnStop and fell back to the console, which called OnStart again.
TrayApplication now records ToolStarted separately: Dispose stops the
tool on it, and RunTray reports the failure and exits 1 instead of
restarting the tool in the terminal.

Fixes #12
Fixes #13

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011tqaKZaJ9nxFMskVoZgreK
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 94dfd58 into main Sep 29, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix-tray-start-sequence branch September 29, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants