fix(bootstrap): surface why the backend "never started" (refs #144, #127) - #148
Conversation
AppImage users hit "Backend process exited (never started) — no error output captured" with nothing to act on. Root gap: when `Command::spawn()` of the venv Python fails (the common Linux/AppImage case — interpreter can't exec, missing system lib, stale venv), spawn_backend logged the OS error but returned None silently, so the bootstrap reported "no error output captured". Now the spawn failure writes a diagnostic (the interpreter path, whether it exists on disk, the OS error, and an actionable "Clean & Retry / run from a terminal" hint) to backend_err.log, which the bootstrap's read_error_log_tail already surfaces. The "no output" dead-end becomes the real launch error. This makes #144/#127 diagnosable (the underlying AppImage cause then routes from the now-visible error). Pure message builder is unit-tested; cargo test + cargo check clean. Refs #144, #127. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR enhances backend spawn error handling by introducing a ChangesBackend spawn failure diagnostic
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| Filename | Overview |
|---|---|
| frontend/src-tauri/src/backend.rs | Adds spawn_failure_diagnostic helper and writes its output to backend_err.log on Command::spawn() failure; adds platform-conditional OS hints and a unit test. Fix is well-scoped and correctly addresses issues #144/#127. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[spawn_backend called] --> B[backend_log_path - create dir]
B --> C[fs::File::create backend_err.log truncates file]
C --> D[ensure_venv_ready - get python path]
D --> E{Command::spawn}
E -->|Ok - child| F[Spawn stderr pipe thread writes to err_log_file]
F --> G[Return Some child]
E -->|Err - e| H[spawn_failure_diagnostic python path + exists + OS error + os_hint]
H --> I[log::error diag]
I --> J[fs::write backend_err.log diag]
J --> K[return None - err_log_file dropped]
K --> L[Bootstrap calls read_error_log_tail shows diagnostic to user]
Reviews (2): Last reviewed commit: "fix(bootstrap): platform-specific spawn-..." | Re-trigger Greptile
| On Linux (especially the AppImage) this usually means the bundled venv \ | ||
| Python can't execute — a missing system library or a stale/incomplete \ | ||
| venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \ | ||
| AppImage from a terminal to see the dynamic-loader error.", |
There was a problem hiding this comment.
The diagnostic hint is tightly coupled to Linux/AppImage terminology. On macOS or Windows a user will see "run the AppImage from a terminal to see the dynamic-loader error" — which is meaningless (there is no AppImage and no dynamic-loader to inspect). The "Clean & Retry" part is universally actionable, but the trailing sentence actively misleads non-Linux users. A platform-conditional hint would keep the message accurate on every OS.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Fixed — the OS-specific tail is now chosen by build target via cfg!(target_os): the AppImage/dynamic-loader wording only on Linux, a venv/quarantine hint on macOS, and a missing-Python/antivirus hint on Windows. The 'Clean & Retry' line stays universal.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src-tauri/src/backend.rs`:
- Around line 145-153: The diagnostic currently logs the full interpreter path
via the python variable when building diag; sanitize any absolute user-home
prefixes before formatting or persisting diagnostics: detect the current user's
home directory (e.g., via dirs::home_dir() or
std::env::var("HOME")/USERPROFILE), and if the python path starts with that home
prefix, replace that prefix with a redacted token like "~" or "[REDACTED_HOME]"
before inserting into the formatted message; apply the same sanitization helper
to all other spawn diagnostic strings (including the occurrences referenced
around the python usage and the additional cases at the later block noted for
lines ~245-247) so no absolute /Users/... or C:\Users\... segments are logged or
persisted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: f44f3781-d1fd-4a48-beea-d2a532a856b9
📒 Files selected for processing (1)
frontend/src-tauri/src/backend.rs
| "Failed to launch the backend process.\n\ | ||
| Tried to run: {}\n\ | ||
| Interpreter present on disk: {}\n\ | ||
| OS error: {}\n\n\ | ||
| On Linux (especially the AppImage) this usually means the bundled venv \ | ||
| Python can't execute — a missing system library or a stale/incomplete \ | ||
| venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \ | ||
| AppImage from a terminal to see the dynamic-loader error.", | ||
| python.display(), |
There was a problem hiding this comment.
Redact user-home prefixes before logging/persisting spawn diagnostics.
The diagnostic now logs and writes the full interpreter path; that can include absolute user-home paths and violates policy. Please sanitize python before formatting diag.
Suggested patch
+fn redact_user_home_path(path: &Path) -> String {
+ let raw = path.to_string_lossy().to_string();
+
+ #[cfg(target_os = "macos")]
+ if let Ok(home) = std::env::var("HOME") {
+ let prefix = format!("{}/", home);
+ if raw.starts_with(&prefix) {
+ return raw.replacen(&home, "~", 1);
+ }
+ }
+
+ #[cfg(target_os = "windows")]
+ if let Ok(home) = std::env::var("USERPROFILE") {
+ if raw.starts_with(&home) {
+ return raw.replacen(&home, "%USERPROFILE%", 1);
+ }
+ }
+
+ raw
+}
+
fn spawn_failure_diagnostic(python: &Path, err: &std::io::Error) -> String {
+ let redacted_python = redact_user_home_path(python);
format!(
"Failed to launch the backend process.\n\
Tried to run: {}\n\
Interpreter present on disk: {}\n\
OS error: {}\n\n\
On Linux (especially the AppImage) this usually means the bundled venv \
Python can't execute — a missing system library or a stale/incomplete \
venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \
AppImage from a terminal to see the dynamic-loader error.",
- python.display(),
+ redacted_python,
python.exists(),
err,
)
}As per coding guidelines, "Flag any code that persists or logs values matching TOKEN/KEY/SECRET or absolute user home paths (/Users//, C:\Users\\)."
Also applies to: 245-247
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src-tauri/src/backend.rs` around lines 145 - 153, The diagnostic
currently logs the full interpreter path via the python variable when building
diag; sanitize any absolute user-home prefixes before formatting or persisting
diagnostics: detect the current user's home directory (e.g., via
dirs::home_dir() or std::env::var("HOME")/USERPROFILE), and if the python path
starts with that home prefix, replace that prefix with a redacted token like "~"
or "[REDACTED_HOME]" before inserting into the formatted message; apply the same
sanitization helper to all other spawn diagnostic strings (including the
occurrences referenced around the python usage and the additional cases at the
later block noted for lines ~245-247) so no absolute /Users/... or C:\Users\...
segments are logged or persisted.
The diagnostic tail said "run the AppImage from a terminal… dynamic-loader error" — meaningless on macOS/Windows (spawn can fail on any OS). Pick the hint by build-target OS via cfg!: AppImage/loader wording on Linux, venv/quarantine on macOS, missing-Python/AV-block on Windows. "Clean & Retry" stays universal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AppImage users get "Backend process exited (never started) — no error output captured" (#144, #127) with nothing actionable.
Root gap
When
Command::spawn()of the venv Python fails — the common Linux/AppImage case (the bundled interpreter can't exec: missing system lib, stale venv, arch mismatch) —spawn_backendlogged the OS error but returnedNonesilently, so the bootstrap surfaced the useless "no error output captured."Fix
On spawn failure, write a diagnostic to
backend_err.log(which the bootstrap'sread_error_log_tailalready reads): the interpreter path, whether it exists on disk, the real OS error, and an actionable hint ("Clean & Retry / run the AppImage from a terminal to see the loader error"). The dead-end becomes the actual launch error.Scope / honesty
This makes the failure diagnosable — it surfaces why the backend won't start. It doesn't blindly guess the specific AppImage root cause (which needs that now-visible error). Once a reporter shares the surfaced message, the underlying cause routes to a targeted fix. Same "errors must be visible" principle as plan-04, applied to the Tauri bootstrap.
Tests
Pure message builder unit-tested (
spawn_failure_diagnostic);cargo test+cargo checkclean. (Full AppImage repro isn't possible in CI.)Refs #144, #127.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests