Skip to content

refactor(runtime): migrate web_search.rs to ToolError (#3576 slice)#6107

Merged
houko merged 7 commits into
mainfrom
refactor/error-contracts-slice
Jun 15, 2026
Merged

refactor(runtime): migrate web_search.rs to ToolError (#3576 slice)#6107
houko merged 7 commits into
mainfrom
refactor/error-contracts-slice

Conversation

@houko

@houko houko commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

One slice of the ongoing structured error-contracts migration (#3576). Migrates crates/librefang-runtime/src/web_search.rs from stringly-typed Result<String, String> to Result<String, ToolError>, reusing existing ToolError variants.

Per docs/architecture/error-contracts.md, the migration intentionally changes the LLM-visible error strings to the variant Display form — affected tests are re-pinned to the exact new strings (strengthened from .contains() to exact .to_string() asserts).

Variant mapping

Failure Variant
absent API key / unconfigured SearXNG URL Unavailable
pageno == 0, invalid category InvalidParameter { name, reason }
reqwest .send()/.json()/.text() failures upstream(e) — preserves the reqwest::Error source chain (#3745)
non-success status, no results, all providers failed upstream_msg(...)

Brave key-rotation logic preserved (matches on e.to_string()). Dispatch boundary still narrows ToolError -> String via Display. Stays in-crate (librefang-runtime); no cross-crate error-shape changes; does not add the clippy::disallowed_types gate.

Test plan

  • cargo clippy -p librefang-runtime --all-targets -- -D warnings (verified: clean)
  • cargo test -p librefang-runtime --lib web_search:: (verified: 24 passed)
  • cargo test -p librefang-runtime --lib tool_runner::error:: (verified: 14 passed)

Refs #3576 (one slice; does not close the issue).

One slice of the structured error-contracts migration. web_search.rs's 9 Result<String,String> tool fns now return Result<String, ToolError>, reusing existing variants: Unavailable for absent API keys / unconfigured SearXNG URL, InvalidParameter for bad pageno/category, upstream() for reqwest failures (preserving the reqwest::Error source chain per #3745), upstream_msg() for no-results / all-providers-failed. Per docs/architecture/error-contracts.md the LLM-visible strings change to the variant Display form; affected tests re-pinned to exact new strings. Brave key-rotation preserved by matching e.to_string(). Dispatch boundary still narrows ToolError->String. No cross-crate changes, no clippy gate added.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 14, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
librefang-deploy 472cd96 Jun 14 2026, 10:43 PM

@github-actions github-actions Bot added size/M 50-249 lines changed area/docs Documentation and guides area/runtime Agent loop, LLM drivers, WASM sandbox ready-for-review PR is ready for maintainer review and removed size/M 50-249 lines changed labels Jun 14, 2026
…HANGELOG

CHANGELOG entry for the web_search ToolError migration had multiple
sentences collapsed onto one line; split to one sentence per line per
the prose-wrapping rule.

Removed #3576 task-reference comments from dispatch.rs and three
two-line comment blocks from the web_search tests — those notes belong
in the PR description, not in code or test comments.
@github-actions github-actions Bot added the size/M 50-249 lines changed label Jun 14, 2026

@houko houko left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed one style commit (e20745c) with three mechanical fixes:

  • CHANGELOG.md: the new entry had four sentences on a single line; split to one sentence per line per the prose-wrapping rule (new prose is in scope).
  • dispatch.rs: removed the // #3576: search() returns Result<String, ToolError>; narrow here. comment added by this PR — task-reference comments belong in the PR body, not in code.
  • web_search.rs tests: removed three // #3576: comment blocks (two were multi-line) above the re-pinned assertions — same reason.

One ambiguous finding left as an inline comment: the search_auto DuckDuckGo fallback arm re-wraps e: ToolError in upstream_msg(format!("… {e}")), which may lose the reqwest::Error source chain the PR says is preserved.


Generated by Claude Code

Ok(_) => Err("All search providers failed; DuckDuckGo returned empty results (likely captcha-blocked). Configure a Brave, Tavily, Jina, Perplexity, or SearXNG provider for reliable search.".to_string()),
Err(e) => Err(format!("All search providers exhausted. Last error (DuckDuckGo): {e}")),
Ok(_) => Err(ToolError::upstream_msg("All search providers failed; DuckDuckGo returned empty results (likely captcha-blocked). Configure a Brave, Tavily, Jina, Perplexity, or SearXNG provider for reliable search.")),
Err(e) => Err(ToolError::upstream_msg(format!("All search providers exhausted. Last error (DuckDuckGo): {e}"))),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Err(e) => arm wraps an existing ToolError in a new upstream_msg(format!("… {e}")), converting e to its Display string and losing whatever source chain e carries (e.g. the reqwest::Error that search_duckduckgo may have returned).

The PR description says reqwest failures are routed via ToolError::upstream to preserve the source chain per #3745, but this specific arm re-wraps rather than propagates.

If the "all providers exhausted" context string matters, one option is to keep upstream_msg here since the message is the deliverable and the chain is already summarised in {e} — but that should be a conscious choice, not a side-effect. If the source chain matters at the dispatch boundary (e.g. for structured logging of the root reqwest::Error), the arm could propagate e directly and let search_auto's callers see the DuckDuckGo error as-is.


Generated by Claude Code

@houko
houko merged commit e4db214 into main Jun 15, 2026
31 checks passed
@houko
houko deleted the refactor/error-contracts-slice branch June 15, 2026 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation and guides area/runtime Agent loop, LLM drivers, WASM sandbox ready-for-review PR is ready for maintainer review size/M 50-249 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants