Skip to content

fix(desktop): surface early daemon spawn failures - #1345

Open
mkdir700 wants to merge 2 commits into
mainfrom
1259-windows-gui-shows-no-error-when-daemon-f
Open

fix(desktop): surface early daemon spawn failures#1345
mkdir700 wants to merge 2 commits into
mainfrom
1259-windows-gui-shows-no-error-when-daemon-f

Conversation

@mkdir700

@mkdir700 mkdir700 commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

  • retain the detached daemon child handle while waiting for /health
  • detect an early child exit and report it separately from a startup timeout
  • render Windows loader NTSTATUS codes with actionable runtime guidance
  • preserve the existing fire-and-forget spawn API for callers that do not watch the child

Root cause

On Windows, CreateProcess can succeed before the image loader discovers a missing runtime DLL. The GUI therefore saw a successful spawn, dropped the child handle, and eventually reported only a generic health timeout. Watching Child::try_wait() during health polling preserves the process exit code and distinguishes a hard launch failure from a slow startup.

Fixes #1259.

Verification

  • cargo check -p uc-daemon-process --quiet
  • cargo test -p uc-daemon-process --lib --quiet (54 passed)
  • cargo test -p uc-desktop daemon_probe --quiet (14 passed)
  • LSP diagnostics on the four affected Rust files: no errors or warnings

Summary by CodeRabbit

  • Bug Fixes
    • Improved daemon startup monitoring to detect processes that exit immediately.
    • Startup failures now surface promptly instead of waiting for the full health-check timeout.
    • Error messages provide clearer exit-code details, including helpful hints for recognized missing or incompatible runtime issues.
    • Daemon restarts now monitor process health and report early failures consistently.
  • Reliability
    • Improved handling of daemon startup timeouts and health-check races for more predictable launch behavior.

mkdir700 added 2 commits July 15, 2026 22:34
`Command::spawn` returning Ok does not prove the daemon is running: on
Windows `CreateProcess` succeeds even when the image loader later fails
to resolve a dependency DLL (e.g. a missing vcruntime140.dll), so the
process is created and then dies within milliseconds. A caller that only
polls /health cannot tell that hard crash apart from a slow start until
the (long) startup timeout elapses.

Add the primitives to distinguish the two:

- spawn_detached_daemon_returning_child hands back the Child handle so a
  caller can watch it; spawn_detached_daemon keeps its fire-and-forget
  contract as a thin drop wrapper.
- poll_child_liveness / ChildLiveness give a transport-neutral view of
  whether the spawned child has already exited, with its exit code.
- wait_for_daemon_health_watching_child mirrors wait_for_daemon_health
  but fails fast with DaemonBootstrapError::SpawnExitedEarly when the
  child exits before /health comes up. Probe-first ordering lets a
  genuinely healthy daemon win a race against a same-tick child exit.
- SpawnExitedEarly renders the NTSTATUS exit code and, for known loader
  codes (STATUS_DLL_NOT_FOUND etc.), points at the likely fix (install
  the Visual C++ Redistributable).

No existing caller behavior changes; the new API is additive.

Refs #1259
On Windows a daemon binary that cannot launch (e.g. a missing
vcruntime140.dll) lets CreateProcess/Command::spawn return Ok, so the
GUI only noticed the failure via the 45s /health startup timeout and
then showed a generic "couldn't reach the background service" — 45s of
what looked like normal loading, followed by an unactionable message.

Hold the spawned Child in spawn_external_and_wait_health and
restart_local_daemon and wait via wait_for_daemon_health_watching_child,
so a launch crash fails fast (~200-400ms) with the exit code and, for a
missing-DLL NTSTATUS, an actionable hint. The failure flows through the
existing DaemonBootstrapStatus -> get_daemon_bootstrap_failure path to
the frontend error screen unchanged (classified Unavailable, with the
actionable detail).

Refs #1259
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
uc-docs Ready Ready Preview, Comment Jul 15, 2026 2:40pm

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b18559ba-2a48-4429-82e3-4d3ba195af5f

📥 Commits

Reviewing files that changed from the base of the PR and between e7aa4a4 and 2eb9941.

📒 Files selected for processing (4)
  • crates/uc-daemon-process/src/contract.rs
  • crates/uc-daemon-process/src/health_wait.rs
  • crates/uc-daemon-process/src/spawn.rs
  • crates/uc-desktop/src/daemon_probe.rs

📝 Walkthrough

Walkthrough

Daemon startup now retains spawned child handles, polls liveness during health checks, and reports immediate exits with optional exit-code details. Desktop bootstrap and restart flows use the new monitoring path.

Changes

Daemon early-exit detection

Layer / File(s) Summary
Bootstrap error and health-wait contracts
crates/uc-daemon-process/src/contract.rs, crates/uc-daemon-process/src/health_wait.rs
Adds SpawnExitedEarly, exit-code formatting with Windows NTSTATUS hints, ChildLiveness, probe-first child-aware health waiting, and coverage for exit, success, precedence, and timeout cases.
Spawn handle and liveness polling
crates/uc-daemon-process/src/spawn.rs
Adds a spawn helper returning Child and maps non-blocking child status checks into ChildLiveness.
Desktop bootstrap integration
crates/uc-desktop/src/daemon_probe.rs
Updates external startup and local restart to retain child handles, monitor liveness during health checks, and drop handles after completion.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Desktop
  participant Spawn
  participant HealthWait
  participant Child
  Desktop->>Spawn: spawn daemon and retain Child
  Spawn-->>Desktop: Child handle
  Desktop->>HealthWait: wait for health with liveness callback
  HealthWait->>Child: poll liveness
  Child-->>HealthWait: Running or Exited with code
  HealthWait-->>Desktop: readiness or bootstrap error
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: surfacing early daemon spawn failures from desktop startup.
Linked Issues check ✅ Passed The PR detects immediate child exits, keeps the child handle during health checks, covers restart flow, and adds actionable Windows runtime hints.
Out of Scope Changes check ✅ Passed The changes stay focused on daemon startup failure handling and related tests, with no obvious unrelated feature work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 1259-windows-gui-shows-no-error-when-daemon-f

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.

@github-actions

Copy link
Copy Markdown
Contributor

No React Doctor issues found. 🎉

Reviewed by React Doctor for commit 2eb9941.

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.64179% with 57 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/uc-desktop/src/daemon_probe.rs 0.00% 34 Missing ⚠️
crates/uc-daemon-process/src/spawn.rs 0.00% 17 Missing ⚠️
crates/uc-daemon-process/src/contract.rs 91.11% 4 Missing ⚠️
crates/uc-daemon-process/src/health_wait.rs 98.09% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

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.

Windows: GUI shows no error when daemon fails to start (e.g. missing vcruntime140.dll)

1 participant