fix(desktop): time out daemon requests and show connection errors - #233
Merged
Merged
Conversation
The desktop IPC client waited forever for a reply, so a daemon that never answers (e.g. one older than #229 asked for a method it does not know) hung the app. Mirror the CLI client from #229: a 10s per-request timeout cleared on reply, write error and close; pending requests rejected on close; and an 'unknown method' error mapped to an update-the-daemon message. The Settings page's Connect button was a simulation; it now calls the real connect-daemon handler and shows the daemon's error. A handshake whose status request fails now reports not connected with the error instead of claiming a connection.
ralyodio
force-pushed
the
fix/desktop-daemon-client-timeout
branch
from
September 25, 2026 16:56
e6344e8 to
7854a5e
Compare
ThreatCrush Security Scan12 finding(s) HIGH/CRITICAL: 1 | MEDIUM: 6 | LOW: 5
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The desktop app's IPC client (
apps/desktop/src/main/daemon-client.ts) now behaves like the CLI client after #229:threatcrushd did not answer "<method>" within 10s; if it is older than this app, update it.daemon connection closed).unknown method: …error becomesthreatcrushd is older than this app (unknown method: …); update it. Other daemon errors pass through unchanged.The client's errors now reach the UI:
setTimeoutsimulation that never contacted the daemon. It now calls the realconnect-daemonhandler and shows the result:Connected to threatcrushd vX at <socket>orNot connected: <error>. The Host/Port fields are gone because the main process ignores them. It only ever connects to the local unix socket.connect-daemonhandshake: if thestatusrequest fails (for example, it times out), the handler used to returnconnected: trueanyway. It now closes the client and returnsconnected: falsewith the error.subscribeis still best-effort.CI: added a
Test desktop appstep to PR checks so the new suite runs.Why
An older daemon (before #229) never replies to a method it doesn't know. The desktop client had no timeout, so any request to such a daemon hung forever.
Why duplicate instead of share
apps/desktopdoesn't depend on the CLI. The CLI'sIpcClientimports the daemon'spaths,control-tokenand protocol modules and has a typed per-method API. The desktop client is a genericrequest(method)with push listeners. Sharing would mean pulling CLI daemon modules into the Electron main bundle, or creating a new shared package, just for about 20 lines. So the logic is duplicated, with a comment pointing atapps/cli/src/core/ipc-client.ts.Verification
apps/desktop/src/main/__tests__/daemon-client.test.tsis a new vitest suite (node env, fake unix socket server in a temp dir), 5 tests. It covers: a never-answered request times out,unknown methodmaps to the update message, other errors pass through, a pending request rejects on close, and an answered request leaves no timer behind.unknown method: top_sources.pnpm --filter @profullstack/threatcrush-desktop buildpasses.pnpm --filter @profullstack/threatcrush test: 28 files, 258 tests pass.out/main/index.js: Electron itself can't launch on the dev host (no GTK libs). The bundle was loaded with only theelectronmodule stubbed. Its realconnect-daemonhandler was bridged to the realSettingspage rendered in jsdom, against a fake daemon.status: the button showsCONNECTING..., then after 10.1s showsCONNECTandNot connected: threatcrushd did not answer "status" within 10s; if it is older than this app, update it.unknown method: status:Not connected: threatcrushd is older than this app (unknown method: status); update it.CONNECTED,Connected to threatcrushd v9.9.9 at ….connect-daemonhandler was still pending when curl gave up at 30s.