Repository navigation
RFC-0047: 错误体系与错误原因(cause) - #286
Merged
Merged
Conversation
Contributor
Author
|
作为贡献者,我(li)对 RFC §10 四个待讨论问题的意见是都按推荐,供维护者参考:
Generated by Claude Code |
This was referenced Oct 19, 2026
Merged
cunninghamcard-bit
marked this pull request as ready for review
October 20, 2026 10:05
3 of 15 tasks
Contributor
Author
4 of 7 tasks
cunninghamcard-bit
force-pushed
the
rfc/0047-error-system-and-cause
branch
from
October 20, 2026 10:48
22f1bfc to
52f2b63
Compare
eric8810
reviewed
Oct 20, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
Review
方向合理,但契约与实现/其他 RFC 还没对齐,暂不建议接受:
- 重要
Retry的lastError没有接到原生 cause 链:wire payload 没有cause,Node/Python/Java/Go 的 cause 都为空。RFC §7 需要明确各绑定如何从errors.last()合成 cause,并补测试。 - 重要 Node 嵌套 cause 是普通对象,不是错误类;Java 实际多了一个手写
ai.arcships.aimux.ErrorCause包装类,RFC 没说明它和生成的types.ErrorCause的分工。 - 重要 §9 的安全声明不准确:serde_json 的 data 错误会引用违规值,
TypeValidation.value也没有大小/脱敏上限;建议增加大小和脱敏边界。 - 重要 §11 低估破坏性:
InvalidToolInput.cause字符串→对象、recordingsource→cause、传输消息去 URL,都不只是“新增可选字段”。 - 重要(跨 RFC) 与 RFC-0048 冲突:RFC-0047 说 schema 2 旧文件可读,RFC-0048 要删除 schema 1/2 读取;
ErrorCause放 core 也与 RFC-0044 的aimux-provider归属不一致。 - 次要 §10 Q2/Q3 已在 #293 实现,建议标为已采纳;Swift 的
SourceError.cause需要 #289 的WireIndirect处理,RFC 未登记。
Describes how aimux's error system differs from the AI SDK's, traces today's error paths from the public entry functions to the lines that drop the underlying error, and designs `cause` across the core, the transport layer, the ops envelope, the generated DTOs and every binding. The open questions in section 10 stay open. Line numbers refer to master 4220847, and the text includes what implementing #289, #290 and #293 found. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S2GJxE3fH7rQvAwXLg2f1C
Retry's lastError as every binding's native cause, the Node and Java cause classes, an accurate security section with a size and redaction question, the full list of breaking changes, Swift's WireIndirect, and how RFC-0044, RFC-0048 and #349 meet this RFC. Q2 and Q3 are marked adopted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S2GJxE3fH7rQvAwXLg2f1C
cunninghamcard-bit
force-pushed
the
rfc/0047-error-system-and-cause
branch
from
October 20, 2026 14:43
52f2b63 to
0d5d7b2
Compare
Contributor
Author
|
回复 @eric8810 的 review(左列是 eric 的原话),正文改动在 0d5d7b2:
另外 §11.1 记下 #349(信封去掉 Generated by Claude Code |
cunninghamcard-bit
pushed a commit
that referenced
this pull request
Oct 20, 2026
Publish order puts aimux before providers so C7 can land before C6; observers ride on DiagnosticScope instead of OperationSettings, with core's Recorder as the C3-C5 observer; C4's download takes connection, user-agent and error-mapping parameters; RFC-0047 cited as #286; line references refreshed at 5743a40. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW
eric8810
approved these changes
Oct 21, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
复审通过。Retry 最后一次尝试的原生 cause、Node/Java 的 cause 类型分工、§9 安全边界、§11 破坏性清单、与 RFC-0048 的 schema 2 关系,以及 Q2/Q3 的采纳状态都已对齐实现。Approve。
eric8810
pushed a commit
that referenced
this pull request
Oct 21, 2026
* docs(rfc): RFC-0044 crate 拆分、依赖反转与 provider 目录布局 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): RFC-0044 录制在 Fetch 层留观察点,上下文传法交给观测 RFC Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * RFC-0044: fold aimux-stream into aimux-provider-utils (L9, C0) aimux-stream is a ~120-line adapter over sse-stream plus an unused extract_lines; its only caller is provider-utils. Upstream keeps SSE decoding in provider-utils over eventsource-parser. Registers the change to alignment doc D17. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * RFC-0044: move provider layout and test placement to RFC-0046 RFC-0044 keeps the crate split and dependency inversion; the per-vendor directory, test placement and cross-vendor reuse rules move to a separate RFC-0046. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * RFC-0044: correct the provider count (48 vendor implementations, 282 presets) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * RFC-0044: apply review corrections Fix the recording, session, download and trace call stacks against master; assign the unassigned modules (decision, files and skills models, math, util, prelude, replay mocks, rebuild_decision_provider); name the three upward edges C2 must cut; add test ownership rules; register the alignment-doc conflicts and list the open questions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * RFC-0044: keep the aimux-core crate name (contributor opinion) Record li's opinion that aimux-core keeps its name instead of the D17 rename to aimux; register the difference for the maintainer to decide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * Revert "RFC-0044: keep the aimux-core crate name (contributor opinion)" Contributor opinions go to PR comments, not the RFC text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): RFC-0044 review fixes: transport call scope in C3, unify observation wording, register devtools differences Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): RFC-0044 links RFC-0046 draft PR Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): RFC-0044 unit tests in foo/tests.rs, public-API tests in tests/it Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): put tests in one tests/ directory per module Follows RFC-0046 section 5: each module directory has a tests/ child, one Rust file per upstream test file; crate tests/ keeps only cross-module scenarios. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): drop the draft note on RFC-0046 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc): answer the review of RFC-0044 Keep ProviderDiscovery beside Provider and turn into_text_stream_part into a free function in aimux. Spell out what DiagnosticScope carries (call id, seq/attempt/parent, exchange counter, observers) and the download parity C4 keeps. Let the C7 rename follow C4 instead of the devtools steps, note that #268 removed the generated aimux_core paths, and plan a final aimux-stream release before C0 deletes it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW * docs(rfc-0044): address the second review round Publish order puts aimux before providers so C7 can land before C6; observers ride on DiagnosticScope instead of OperationSettings, with core's Recorder as the C3-C5 observer; C4's download takes connection, user-agent and error-mapping parameters; RFC-0047 cited as #286; line references refreshed at 5743a40. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW --------- Co-authored-by: Claude <noreply@anthropic.com>
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.
Requested by li · project thread
Summary
本 RFC 写清楚 aimux 的错误体系和 AI SDK 哪里不同、为什么不同,并设计
cause:AI SDK 哪个错误类接受cause,aimux 对应变体就带一个可序列化的cause字段;它就是 Rust 的source(),经过 ops 信封、#268 生成的 DTO,到每种语言的原生 cause。下面先是错误体系的概览,再是本 PR 设计的改动细节。错误体系概览
非流式调用(以 OpenAI 为例),行号是 master
42208472(#268 合并后):流式调用:重试只包住拿到第一个事件之前,之后的错误作为事件交付。
跨语言:同一个错误在 ops 边界投影成信封一次,各语言从信封还原。
✗是丢掉底层错误的地方。分类只看结构化字段(status_code、is_retryable、response_headers),这一点不变。每个✗的逐段调用栈和上游同一位置的写法见 RFC §2.1–§2.8。本 PR 的改动
本 PR 只加
rfc/0047-error-cause.md,不改代码。下面是 RFC 设计的改动落在哪条路径、改成什么样(RFC §4–§7)。Rust 类型(RFC §4.1–§4.2):
网络层,概览里前四个
✗(RFC §4.3):ops 信封,概览里跨语言的两个
✗(RFC §5、§7):DTO(RFC §6,#268 的生成器):
实现分三个代码 PR,一个叠一个,最底下一个基于 #268 合并后的 master,用它的生成器:#289 核心类型和网络层,#290 字符串变体(含
TypeValidation和下载错误去 URL),#293 ops 和绑定。#280 是原型实现,拆分后关闭。实现时发现的几处已写进正文(§2.6、§2.7、§4.2、§11–§13)。eric 10-20 的 review 已答进正文:§7 重试的lastError作为各语言原生 cause、Node 和 Java 的 cause 类,§9 安全说明改准确,§11 列全破坏性变更,§11.1 与 RFC-0044、RFC-0048、#349 的关系,§6 登记 SwiftWireIndirect;§10 问题 2、3 标为已采纳,新增问题 5(大小和脱敏边界),问题 1、4、5 待讨论。执行清单在 #327。Type of change
Checklist
cargo fmt --all -- --checkpassescargo clippy --workspace --all-targets -- -D warningspassescargo test --workspacepasses (cassette playback — no network/keys)README.md,docs/,rfc/,bindings/README.md)只改
rfc/,不涉及代码检查。Notes for reviewers
cause形状)、§6([15/15] feat!: generate binding DTOs from the Rust types #268 生成器如何生成ErrorCause)。