Documentation
¶
Overview ¶
Package apierror 提供 API 错误类型定义,供 api 和 retry 包共享.
这避免了 api 包和 retry 包之间的循环依赖.
HTTP error classification -- the protocol-neutral DefaultClassifier (pure HTTP status-code mapping) plus connection-error diagnosis. Kept in the apierror package so both the wire path and the transport path share one classifier without importing each other; provider-specific classifiers (e.g. AnthropicClassifier) stay in the transport layer and delegate here.
HTTP 错误分类 -- 协议无关的 DefaultClassifier (纯 HTTP 状态码映射) 加连接 错误诊断. 放在 apierror 包, 使 wire 路径和 transport 路径共用同一套分类器 而不互相 import; 供应商特定分类器 (如 AnthropicClassifier) 留在 transport 层并委托到这里.
HTTP error structuring -- the APIError type plus response-body and header parsers. These live in the neutral apierror package (rather than the transport/api package) so that both the wire path and the transport path can construct and consume one structured error type without a circular dependency.
HTTP 错误结构化 -- APIError 类型加响应体 / 响应头解析器. 这些放在中立的 apierror 包 (而非 transport/api 包), 使 wire 路径和 transport 路径都能 构造并消费同一套结构化错误类型, 不产生循环依赖.
Index ¶
- func IsSSLErrorCode(code string) bool
- func ParseAPIErrorBody(body []byte) (errorType, message string)
- func ParseRetryAfter(value string) time.Duration
- func ParseShouldRetry(value string) *bool
- func ParseTokenGap(message string) int
- func SanitizeErrorHTML(message string) string
- type APIError
- func (e *APIError) AnalyticsTag() string
- func (e *APIError) Category() string
- func (e *APIError) Error() string
- func (e *APIError) Headers() http.Header
- func (e *APIError) IsRetryable() bool
- func (e *APIError) Message() string
- func (e *APIError) RetryDelay() time.Duration
- func (e *APIError) RetryInfo() *RetryInfo
- func (e *APIError) Unwrap() error
- type DefaultClassifier
- type ErrorCategory
- type RetryInfo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsSSLErrorCode ¶
IsSSLErrorCode 检查给定的错误码或消息片段是否为 SSL/TLS 相关.
func ParseAPIErrorBody ¶
ParseAPIErrorBody 从 API JSON 响应体中提取错误类型和消息.
API 错误响应格式:
{"type":"error","error":{"type":"invalid_request_error","message":"..."}}
精妙之处(CLEVER): 不做完整 JSON 反序列化--只提取两个字段, 避免为错误路径引入复杂的类型定义.手动 JSON 解析虽然"丑",但错误路径 需要最大的容错能力,半格式化的 JSON 也要尽量提取信息.
func ParseRetryAfter ¶
ParseRetryAfter 从 retry-after header 值解析等待时间. 支持秒数格式("30").
func ParseShouldRetry ¶
ParseShouldRetry 从 x-should-retry header 解析服务端重试建议. 返回 nil 表示服务端未表态.
func ParseTokenGap ¶
ParseTokenGap 从错误消息中提取 prompt_too_long 的 token 溢出量. 返回 0 表示无法解析.
func SanitizeErrorHTML ¶
SanitizeErrorHTML 清理可能包含 HTML 的错误消息.
精妙之处(CLEVER): CloudFlare,AWS ALB 等网关在故障时返回 HTML 错误页(而非 JSON). 这些 HTML 如果原样传给 LLM 会浪费几千 token.提取 <title> 标签文本作为简洁消息. 如果没有 HTML 则原样返回.
Types ¶
type APIError ¶
type APIError struct {
// ErrCategory 是错误的语义分类
ErrCategory ErrorCategory
// StatusCode 是 HTTP 状态码(连接错误时为 0)
StatusCode int
// Msg 是原始错误消息(可能来自 API JSON body 或网络错误)
Msg string
// Hint 是用户可操作的诊断提示(如 "检查企业代理的 SSL 证书")
Hint string
// Retry 是重试建议(nil 表示使用 ErrCategory 默认行为)
Retry *RetryInfo
// TokenGap 是 prompt_too_long 时溢出的 token 数(用于响应式压缩跳步).
// 精妙之处(CLEVER): 从 "137500 tokens > 135000 maximum" 中提取差值 2500,
// 让压缩模块一步跳过 2500 token 的消息组,而非逐个尝试.
// 仅在 ErrCategory == ErrPromptTooLong 时有意义.
TokenGap int
// RespHeaders 是保留的响应头(用于下游消费者提取供应商特定信息)
RespHeaders http.Header
// Body 是原始响应体(用于调试和日志)
Body string
// Cause 是底层错误(网络错误时保留原始 error 链)
Cause error
}
APIError 是结构化的 API 错误,实现 error 接口.
升华改进(ELEVATED): 所有错误信息在创建时一次性解析填充-- Category(分类),RetryInfo(重试),TokenGap(压缩跳步),Hint(用户提示). 消费者只读字段,不做二次解析.
替代方案:<原方案每个消费者各自 instanceof + string includes 做分类>
func (*APIError) AnalyticsTag ¶
AnalyticsTag 返回用于分析系统的标准化标签字符串.
func (*APIError) Error ¶
Error implements the error interface. The output line includes every structured field populated at construction time -- Hint, TokenGap, and a truncated Body preview. Previous revisions read only StatusCode / ErrCategory / Msg; the other three were filled by the classifier but silently dropped, so each log line showed half the diagnostic that the struct carried. Body is truncated to 256 bytes to keep lines log-friendly; the full body stays on the APIError and can be read directly by debug tooling when needed.
Previous implementation retained for reference:
if e.StatusCode > 0 {
return fmt.Sprintf("api: HTTP %d [%s]: %s", e.StatusCode, e.ErrCategory, e.Msg)
}
return fmt.Sprintf("api: [%s]: %s", e.ErrCategory, e.Msg)
Error 实现 error 接口. 输出行包含构造时填充的所有结构字段 -- Hint / TokenGap / Body 截断预览. 旧版本只读 StatusCode / ErrCategory / Msg, 其他三个字段由 classifier 填了但被静默丢弃, 每条日志只能看到结构体 携带一半的诊断信息. Body 截到 256 字节保持日志可读; 完整 body 仍挂 在 APIError 上, debug 工具需要时直接读字段.
原实现保留供参照, 见上方 godoc.
func (*APIError) IsRetryable ¶
IsRetryable 返回是否建议重试. 优先使用 Retry 的精确判断,fallback 到 ErrCategory 默认行为.
type DefaultClassifier ¶
type DefaultClassifier struct{}
DefaultClassifier 是基于 HTTP 状态码的默认分类器. 不解析任何供应商特定的 header 或 body 内容,作为兜底分类器使用.
type ErrorCategory ¶
type ErrorCategory int
ErrorCategory 是 API 错误的语义分类枚举.
const ( ErrUnknown ErrorCategory = iota ErrAborted ErrTimeout ErrRateLimit ErrOverloaded ErrPromptTooLong ErrMediaTooLarge ErrRequestTooLarge ErrInvalidRequest ErrAuthentication ErrModelNotFound ErrBilling ErrServerError ErrConnection ErrSSL ErrToolMismatch ErrUnexpectedTool ErrDuplicateToolID ErrInvalidModel ErrContentPolicy )
func (ErrorCategory) IsRetryableByDefault ¶
func (c ErrorCategory) IsRetryableByDefault() bool
IsRetryableByDefault 返回该分类是否默认可重试.
func (ErrorCategory) String ¶
func (c ErrorCategory) String() string
String 返回分类的分析用字符串(Datadog tag 等).