pref:增加错误时重试功能#108
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更说明
本次 PR 建立了 NeoCode provider 层的统一错误处理体系,并在 HTTP 传输层和 Runtime 层分别引入了两级互补的自动重试机制,同时保证了 SSE 流式传输中途断连时的优雅降级。
主要改动
1. 统一 ProviderError 错误体系
新增文件:
internal/provider/errors.go、internal/provider/errors_test.goProviderError结构体,包含StatusCode、Code(语义分类)、Message、Retryable字段,实现error接口parseError(openai.go)基于 HTTP 状态码 + 可选的 body JSON message 做简单映射,不 追求覆盖 OpenAI 私有错误码(如invalid_api_key、model_not_found),只处理通用 HTTP 语义classifyStatus将标准 HTTP 状态码映射为 9 种ProviderErrorCode:auth_failed、forbidden、not_found、client_error、rate_limited、server_error、timeout、network_error、unknownIsRetryableStatus判定 429 和 5xx 为可重试,上层通过errors.As(err, &pErr)类型断言获取Retryable标记NewProviderErrorFromStatus、NewNetworkProviderError、NewTimeoutProviderError2. HTTP 层重试 — RetryTransport
新增文件:
internal/provider/transport/retry.gohttp.RoundTripper接口的中间件RetryTransport,在首次请求阶段自动重试可恢复错误DefaultRetryableFunc:ProviderError.Retryable == true或网络层错误(连接拒绝、超时、DNS 失败)时触发重试3. OpenAI Provider 集成
修改文件:
internal/provider/openai/openai.goNew(cfg, opts ...BuildOption)引入 functional option 模式,WithTransport(rt)支持注入任意http.RoundTripperDriver()的Build默认注入RetryTransport(DefaultRetryConfig())consumeStream在io.EOF时 flush 已缓冲数据,通过finalizeResponse返回已累积的内容、tool calls 和 usage,保证"有部分结果总比没有好"的降级行为4. Runtime 层重试
修改文件:
internal/runtime/runtime.go、internal/runtime/events.go、internal/runtime/runtime_test.gocallProviderWithRetry方法:在 Transport 层重试耗尽后,Runtime 层仍可重试整个provider.Chat()调用(默认最多 2 次)EventProviderRetry事件类型,向 TUI 通知重试进度ProviderError.Retryable判断是否值得重试,非可重试错误直接返回5. 两级重试协作关系
预期收益
ProviderError收敛所有 provider 错误,上层(runtime、TUI)无需关心底层厂商差异,通过errors.As类型断言即可获取结构化错误信息consumeStream返回已接收的部分内容,而不是丢弃已有进度报错,用户体验从"请求失败"降级为"结果不完整"WithTransportfunctional option 支持注入任意http.RoundTripper,便于未来接入日志、metrics、mock 等中间件EventProviderRetry事件让 TUI 能展示重试进度,用户可以感知到系统在自动恢复Fixes #100