Skip to content

Commit 371fa4b

Browse files
roli-lpciclaude
andcommitted
v0.0.8 polish: CLI catches all socket errors, not just URLError
CAUGHT BY CLEAN-VENV INSTALL TEST (Roli requested isolated install verification before sharing with technical friends): `fidelis health` against the live local fidelis-server crashed with a Python traceback (ConnectionResetError: [Errno 54] Connection reset by peer) instead of a clean error message. Root cause: cli.py:_get and _post caught only urllib.error.URLError. Socket-level failures (ConnectionResetError, BrokenPipeError, TimeoutError) are OSError subclasses, NOT URLError. They escaped the handler and showed a 30-line traceback to the user. Fix: - Added _server_error() helper that prints a multi-line clean error (server URL, error reason, two next-step hints) and exits 1. - Both _get and _post now catch (URLError, OSError, JSONDecodeError) — the full family of failure modes a user might hit: * ECONNREFUSED → URLError (server not running) * ECONNRESET → OSError (server crashed mid-response — pre-existing intermittent fidelis-server behavior) * Timeout → OSError (server slow / hung) * HTTP 500 with broken-pipe → OSError * Server returns non-JSON → JSONDecodeError UX before: Traceback (most recent call last): File '...', line 6, in <module> sys.exit(main()) [30 lines of stack trace] ConnectionResetError: [Errno 54] Connection reset by peer UX after: Error: fidelis-server unreachable or unhealthy at http://127.0.0.1:19420 reason: [Errno 54] Connection reset by peer • If you haven't installed the service: `fidelis init` • If the service is installed: `tail ~/.fidelis/server.log` Verified: - exit code 1 on real failure - exit code 0 on server-up success - no false positives (server-up health check still returns clean output) Tests: 375 scaffold tests still passing. This was the kind of UX bug a friend share would have hit on first run. Caught + fixed before any external share. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3dc1748 commit 371fa4b

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

src/fidelis/cli.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ def _base_url() -> str:
3131
return f"http://127.0.0.1:{port}"
3232

3333

34+
def _server_error(exc: BaseException) -> None:
35+
"""Print a clean error + exit. Catches the full family of socket-level
36+
failures so users never see a Python traceback for server-side issues."""
37+
msg = str(exc) or type(exc).__name__
38+
print(f"Error: fidelis-server unreachable or unhealthy at {_base_url()}", file=sys.stderr)
39+
print(f" reason: {msg}", file=sys.stderr)
40+
print(" • If you haven't installed the service: `fidelis init`", file=sys.stderr)
41+
print(f" • If the service is installed: `tail ~/.fidelis/server.log`", file=sys.stderr)
42+
sys.exit(1)
43+
44+
3445
def _post(path: str, payload: dict) -> dict:
3546
data = json.dumps(payload).encode()
3647
req = urllib.request.Request(
@@ -42,20 +53,16 @@ def _post(path: str, payload: dict) -> dict:
4253
try:
4354
with urllib.request.urlopen(req, timeout=30) as resp:
4455
return json.loads(resp.read())
45-
except urllib.error.URLError:
46-
print(f"Error: fidelis-server not reachable at {_base_url()}", file=sys.stderr)
47-
print("Run `fidelis init` to install + start the service.", file=sys.stderr)
48-
sys.exit(1)
56+
except (urllib.error.URLError, OSError, json.JSONDecodeError) as e:
57+
_server_error(e)
4958

5059

5160
def _get(path: str) -> dict:
5261
try:
5362
with urllib.request.urlopen(f"{_base_url()}{path}", timeout=5) as resp:
5463
return json.loads(resp.read())
55-
except urllib.error.URLError:
56-
print(f"Error: fidelis-server not reachable at {_base_url()}", file=sys.stderr)
57-
print("Run `fidelis init` to install + start the service.", file=sys.stderr)
58-
sys.exit(1)
64+
except (urllib.error.URLError, OSError, json.JSONDecodeError) as e:
65+
_server_error(e)
5966

6067

6168
def _print_memories(memories: list, method: str = ""):

0 commit comments

Comments
 (0)