From e323ab76cc534e823a0bf2552950791572fb2f0b Mon Sep 17 00:00:00 2001 From: ZdenekSrotyr Date: Mon, 4 May 2026 20:36:30 +0200 Subject: [PATCH] fix(snapshot): catch httpx transport errors in --estimate path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI failure: test_readers_in_pre_init_dir asserted no Traceback in stderr when running `agnes snapshot create x --as y --estimate` in a folder that never saw `agnes init`. The estimate-guard fix in 3d587681 let `--estimate` skip the local_db check and reach `api_post_json`, but the existing `except V2ClientError` doesn't cover transport-layer failures. With no server configured the URL defaults to http://localhost:8000; httpx raises ConnectError → ConnectError isn't a V2ClientError → the exception bubbles up through Typer/rich as a full traceback. Add `except httpx.HTTPError` next to V2ClientError so connection / DNS / TLS / timeout failures all render the friendly hint `Run `agnes init …` first` instead of leaking transport noise. --- CHANGELOG.md | 1 + cli/commands/snapshot.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfdd41d..a30baee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ End-to-end clean-analyst-bootstrap rewrite. The web `/setup?role=analyst` page n - `agnes snapshot create` (formerly `da fetch`) no longer materializes an empty `user/duckdb/analytics.duckdb` when run before any `agnes pull`. Friendly hint redirects to `agnes pull`. - Workspace `agnes status` reads from the canonical `server/parquet/` and `user/duckdb/analytics.duckdb` paths (was reading legacy `data/parquet/`, `data/metadata/last_sync.json`). - `agnes init` and `agnes pull` errors now use the `cli/error_render.py` typed-error renderer (added in 0.32.0), so analyst-facing error UX matches the structured shape `agnes query --remote` already produces. +- `agnes snapshot create … --estimate` in a pre-init directory no longer leaks an httpx `ConnectError` traceback to stderr. The estimate-guard fix (3d587681) let `--estimate` reach `api_post_json`, but the existing `except V2ClientError` clause didn't catch transport-layer errors when no server was configured (defaulted to `http://localhost:8000`). Now also catches `httpx.HTTPError` and renders the friendly hint `Run \`agnes init …\` first`. - `agnes push` now reads Claude Code session jsonls from `~/.claude/projects//` (where Claude Code actually writes them), instead of `/user/sessions/` (which the SessionEnd hook never populated — the previous code uploaded an empty list every time). Encoding logic in `cli/lib/claude_sessions.py` probes both Claude Code variants — older `/`→`-` and newer all-non-alphanumeric→`-` — and unions the result, so users who have upgraded Claude Code mid-project see sessions from both encoded dirs. Falls back to `/user/sessions/` for back-compat. ### Removed diff --git a/cli/commands/snapshot.py b/cli/commands/snapshot.py index d2a73c9..1a4a5f3 100644 --- a/cli/commands/snapshot.py +++ b/cli/commands/snapshot.py @@ -8,6 +8,7 @@ from datetime import datetime, timedelta, timezone from pathlib import Path import duckdb +import httpx import pyarrow.parquet as pq import typer @@ -272,6 +273,17 @@ def create_cmd( except V2ClientError as e: typer.echo(f"Error: estimate failed: {e}", err=True) raise typer.Exit(_exit_code_for(e)) + except httpx.HTTPError as e: + # Connection refused / DNS / TLS / timeout — friendly render so + # `agnes snapshot create … --estimate` in a pre-init dir (no + # server configured, defaults to http://localhost:8000) prints + # a hint instead of leaking an httpx traceback to stderr. + typer.echo( + f"Error: could not reach server ({e.__class__.__name__}). " + f"Run `agnes init --server-url --token ` first.", + err=True, + ) + raise typer.Exit(7) typer.echo(f"Estimate for {table_id}:") _print_estimate(est) if estimate: