Skip to content

Web Tools 错误码

本文定义内置 web tools(web_search / fetch_content / get_search_content)的结构化错误码。工具 API 见 web-tools.md,provider 行为见 web-providers.md,配置见 configuration.md

Canonical source:

  • 完整错误码清单以 src/modules/web/errors.ts 中的 WEB_ERROR_CODES 为准。
  • 实际返回结构参考 src/modules/web/types.tsWebToolError
  • 具体返回路径参考 src/modules/web/search.tssrc/modules/web/fetch.tssrc/modules/web/storage.tssrc/modules/web/providers/select-provider.ts
  • 如果 README / README.zh 与本文档不一致,以本文档和源码为准。README 只保留常见错误说明,不作为完整错误码清单。

错误返回结构:

json
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  }
}

message 是面向调用方的可操作提示,可能随版本优化;自动化逻辑应优先使用 code

状态定义

Status含义
active当前有直接返回路径
reserved已在 WEB_ERROR_CODES 中定义,但当前没有直接返回路径;保留给未来稳定细化
deprecated旧名称或历史文档名称,不再作为 canonical code 返回

当前 canonical 错误码清单

下表覆盖 WEB_ERROR_CODES 中当前定义的全部错误码。

Error codeStatusMeaningTypical causeReturned byRetryableRelated source
INVALID_INPUTactive通用输入或 provider 配置无效缺少 url/responseId;不支持的 provider;显式 provider 未启用或缺少 endpointfetch_contentget_search_content、provider selectionfetch.tsstorage.tsproviders/select-provider.ts
NOT_FOUNDactive已存储结果或 selector 未命中responseId 不存在;urlIndex/queryIndex 越界;指定 url/query 不存在get_search_contentstorage.ts
WEB_SEARCH_FAILEDactive搜索失败的兜底错误provider 抛出未分类错误;provider 响应解析失败;auto mode 没有 provider 成功完成web_search、provider selection视情况;源码 recovery 建议为 fallbackerrors.tssearch.tsproviders/select-provider.ts
WEB_SEARCH_TIMEOUTactive搜索超时或被 abortprovider 请求超时;调用被 AbortSignal 中止web_searcherrors.tssearch.tsabort.ts
WEB_SEARCH_NO_RESULTSreserved预留:搜索无结果当前设计中"无结果"是成功响应:results = [],不是错误当前不直接返回errors.ts、providers
WEB_SEARCH_INVALID_QUERYactive查询为空或无有效内容query 缺失,或 query/queries trim 后为空web_searchsearch.ts
CONTENT_FETCH_FAILEDactive内容抓取/提取失败的兜底错误URL 安全策略拒绝;HTTP 非 2xx;不支持内容类型;二进制内容;重定向异常;Jina 请求异常;queue full 等未分类 fetch 错误fetch_content通常否;取决于 messagefetch.tssecurity.tshandlers.tsconcurrency.ts
CONTENT_FETCH_TIMEOUTactive内容抓取超时或被 abort主 fetch 请求或 Jina 请求超时/被中止fetch_contenterrors.tsfetch.tsabort.ts
CONTENT_FETCH_INVALID_URLactiveURL 格式或协议无效URL 无法被 new URL() 解析;协议不是 HTTP/HTTPSfetch_contentfetch.tssecurity.ts
CONTENT_FETCH_TOO_LARGEreserved预留:响应体过大当前实现使用 maxResponseBytes / maxContentChars 截断,不把截断视为错误当前不直接返回errors.tsfetch.ts
PROVIDER_RATE_LIMITEDactiveprovider 限流provider 返回 HTTP 429web_searcherrors.tssearch.ts、providers
PROVIDER_UNAVAILABLEactiveprovider 临时不可用provider 返回 HTTP 5xxweb_searcherrors.tssearch.ts、providers
PROVIDER_AUTH_FAILEDactiveprovider 认证失败API key 缺失或无效;HTTP 401/403web_searcherrors.tssearch.ts、providers
NETWORK_ERRORactive搜索 provider 网络连接错误fetch failed、DNS ENOTFOUNDECONN*web_searcherrors.tssearch.ts
PARSE_ERRORreserved预留:解析失败当前 provider JSON parse/response shape 异常通常归入 WEB_SEARCH_FAILED;content handler 解析失败通常 fallback 并设置 parseWarning当前不直接返回errors.ts、providers、handlers.ts
CACHE_ERRORreserved预留:cache 操作失败当前 search cache 是 best-effort,本地 cache/storage 超限通过淘汰或截断处理当前不直接返回errors.tscache.tsstorage.ts

六个预留/边界错误码的处理结论

Error code当前结论是否直接返回说明
WEB_SEARCH_NO_RESULTS保留为 reserved当前语义稳定为成功空结果,不应把 results = [] 改成错误。
WEB_SEARCH_INVALID_QUERY保留并启用空 query 是稳定、可测试的输入错误,直接返回该 code。
CONTENT_FETCH_INVALID_URL保留并启用URL 解析失败和非 HTTP/HTTPS 协议可稳定区分,直接返回该 code。
CONTENT_FETCH_TOO_LARGE保留为 reserved当前实现截断读取/输出,不把"过大但已截断"视为失败。
PARSE_ERROR保留为 reserved当前解析失败多为 fallback 或 provider 兜底错误,暂不引入跨 provider 解析层级。
CACHE_ERROR保留为 reserved当前 cache/storage 不作为用户可感知失败路径暴露。

按场景说明

web_search 输入与无结果

  • 空 query 或 trim 后无有效 query:返回 WEB_SEARCH_INVALID_QUERY
  • provider 返回空结果:工具成功返回,结果为 results = [],不返回 WEB_SEARCH_NO_RESULTS
  • WEB_SEARCH_NO_RESULTS 仅作为未来可能改变无结果语义时的 reserved code。

Provider 配置、认证与请求失败

  • 显式 provider 不支持、未启用或 endpoint 配置无效:INVALID_INPUT
  • API key 缺失、HTTP 401/403:PROVIDER_AUTH_FAILED
  • HTTP 429:PROVIDER_RATE_LIMITED
  • HTTP 5xx:PROVIDER_UNAVAILABLE
  • 网络连接错误:NETWORK_ERROR
  • provider JSON parse 或响应 shape 异常:当前继续归入 WEB_SEARCH_FAILED,暂不直接返回 PARSE_ERROR。对当前用户来说,这类异常与普通 provider 失败的处理动作基本一致;未来如果 structured parser、convert_content 或强 schema 校验变复杂,再启用 PARSE_ERROR

fetch_content URL 与安全策略

  • 缺少 url/urlsINVALID_INPUT
  • URL 格式非法,或协议不是 HTTP/HTTPS:CONTENT_FETCH_INVALID_URL
  • fetch_content 的 URL 校验/安全边界可能拒绝 localhost、私网地址、私有 hostname、DNS 解析到私网地址、非允许协议等 URL。
  • localhost/private IP、私有 hostname、DNS 解析到私网地址等安全策略拒绝:继续归入 CONTENT_FETCH_FAILED。这类失败不是"URL 格式无效",而是安全边界拒绝;当前不新增独立错误码。未来如果调用方需要区分普通 fetch 失败和安全策略拒绝,再考虑新增类似 CONTENT_FETCH_BLOCKED_BY_SECURITY_POLICY 或 CONTENT_FETCH_BLOCKED 的 canonical code。

fetch_content 内容类型与大小限制

  • PDF、Office、ZIP、图片、音视频、可执行文件、magic bytes 检测到二进制内容:当前归入 CONTENT_FETCH_FAILED。对于 PDF、Office 等文档格式,错误信息可能提示下一步改用 convert_content
  • maxResponseBytesmaxContentChars 当前用于截断读取/输出;截断结果通过 truncated: true 表示,不返回 CONTENT_FETCH_TOO_LARGE
  • 当前保持"截断成功"的语义:fetch_content 面向 agent 阅读,截断内容通常比直接失败更有用。
  • 如果未来增加 strict/full mode 或 allowTruncate=false,可启用 reserved code CONTENT_FETCH_TOO_LARGE

Extraction / handler failure

  • content handler 解析失败时优先 fallback 为纯文本,并设置 parseWarning
  • 未分类异常由 fetch_content 汇总为 CONTENT_FETCH_FAILED
  • 当前不直接返回 PARSE_ERROR,避免把可恢复的解析 fallback 变成用户可见错误。

Cache / storage

  • get_search_content 未命中:NOT_FOUND
  • search cache 当前是 best-effort;关闭 cache 是正常配置,不是错误。
  • storage 超出限制通过淘汰或截断处理,不返回 CACHE_ERRORSTORAGE_FULL

Concurrency / connection pool

  • queue full 当前继续归入 CONTENT_FETCH_FAILEDWEB_SEARCH_FAILED,不新增 QUEUE_FULL / CONCURRENCY_LIMITED
  • connection pool / fetch 底层异常会按调用路径归入 CONTENT_FETCH_FAILEDWEB_SEARCH_FAILEDNETWORK_ERROR

Jina fallback

  • Jina fallback 是 fetch_content 内部补救机制,不是用户直接选择的独立 provider。
  • Jina 返回非 2xx 或空内容:fallback 为原始 HTML 结果,不返回错误。
  • Jina timeout/abort:可能返回 CONTENT_FETCH_TIMEOUT
  • Jina 其他请求异常:可能归入 CONTENT_FETCH_FAILED
  • 当前不新增 JINA_* 错误码;如未来 Jina 成为用户可显式选择/观测的 provider,再考虑细化。

HTTP 状态码映射

当前 mapHttpStatusToError() 用于 search provider 错误分类:

Status映射到Retryable
401PROVIDER_AUTH_FAILED
403PROVIDER_AUTH_FAILED
429PROVIDER_RATE_LIMITED
500PROVIDER_UNAVAILABLE
502PROVIDER_UNAVAILABLE
503PROVIDER_UNAVAILABLE
504PROVIDER_UNAVAILABLE
其他WEB_SEARCH_FAILED依具体 recovery

Recovery 动作说明

src/modules/web/errors.ts 为部分错误码定义了 recovery 建议:

Action含义
retry稍后重试当前请求
fallback尝试其他 provider 或 Jina fallback
skip跳过当前内容
abort配置或输入错误,通常不应自动重试

并非所有实际返回的 WebToolError 都携带 recovery 字段;当前 tool 返回结构只保证 error.codeerror.message

Phase 6 的 web/convert 联动明确保持 message-based follow-up guidance。fetch_content 对疑似文档格式可以在 error.message 中提到 convert_content,但不公开 suggestionnextActionsuggestedTool 等字段。只有当多个模块都需要统一的结构化建议时,才应新增 shared structured suggestion schema。

Deprecated / not canonical names

以下名称不是当前 canonical code,不应在 README 或用户文档中写成已实现专用 code:

  • FETCH_CONTENT_FAILED:deprecated 旧名称;当前 canonical code 是 CONTENT_FETCH_FAILED
  • CONTENT_TOO_LARGE:deprecated/旧文档名称;当前 canonical reserved code 是 CONTENT_FETCH_TOO_LARGE
  • STORAGE_FULL:未实现;当前 storage 使用条目上限淘汰和内容截断。
  • CACHE_DISABLED:未实现;关闭 cache 是正常配置。
  • JINA_TIMEOUT / JINA_FAILED:未实现;当前没有独立 Jina 错误码。
  • QUEUE_FULL / CONCURRENCY_LIMITED:未实现;queue full 不作为独立 web error code 暴露。

Future hardening

  • 如需更强类型约束,WebToolError.error.code 已可与 WebErrorCode 对齐;外部 JSON 结构仍保持字符串兼容。
  • 如果未来 provider 统一抛出可识别的 parse/shape 错误,或 structured parser / convert_content / 强 schema 校验变复杂,可将该类错误从 WEB_SEARCH_FAILED 细化为 PARSE_ERROR
  • 如果未来 fetch_content 增加 strict/full mode 或 allowTruncate=false,可启用 CONTENT_FETCH_TOO_LARGE
  • 如果未来调用方需要区分普通 fetch 失败和安全策略拒绝,可新增类似 CONTENT_FETCH_BLOCKED_BY_SECURITY_POLICY 或 CONTENT_FETCH_BLOCKED 的 canonical code。
  • 如果未来 cache/storage 失败成为用户可感知错误,可启用 CACHE_ERROR