refactor(axvm): introduce typed domain errors#1590
Conversation
There was a problem hiding this comment.
审查结论:APPROVE
此 PR 将 axvm 的错误处理从通用 ax-errno 重构为领域类型 AxVmError/AxVmResult,并将 AxVisor 应用层迁移到 anyhow。改动设计合理,实现干净,所有本地验证均通过。
实现分析
AxVmError:使用thiserror::Error派生,覆盖配置、输入、状态、生命周期转换、资源、Boot、Memory、Device、Vcpu、Interrupt 和 Host 等 17 个领域变体,每个变体携带操作名和上下文详情。这符合book/guideline/code-quality.md第 5.3 节对库 crate 使用具体错误类型的要求。VmLifecycleError删除:生命周期状态机直接使用AxVmError::invalid_transition(),Destroy变体的功能已被AxVmError::InvalidTransition和destroy()返回的AxVmResult覆盖。axvm-types兼容:axvm-typescrate 中的VmArchVcpuOps/VmArchPerCpuOpstrait 仍使用ax_errno类型别名(如axvm_types::AxVmResult),aarch64 模块将其导入为BackendResult,在私有arm_result/arm_error_to_ax适配层转换。这是 PR 描述中说明的"共享组件维持现有契约"策略,设计合理。- AxVisor anyhow 迁移:
config.rs、manager.rs、shell/command/vm.rs统一使用anyhow::Result并附加.with_context()提供 VM ID 和操作阶段上下文,错误信息从{e:?}升级为{e:#}完整错误链。main.rs 的expect也改为unwrap_or_else(|error| panic!("failed to initialize AxVM manager: {error:#}")),提高了诊断质量。 BootImageProvidertrait:返回类型从AxResult改为AxVmResult,文件操作错误通过boot_file_error()辅助函数转换为AxVmError::Boot领域错误,携带操作类型和文件名。
验证结果
| 验证项 | 状态 |
|---|---|
cargo fmt --check |
✅ 通过 |
cargo xtask clippy --package axvm(6 个 feature 组合) |
✅ 全部通过 |
cargo test -p axvm --test error_contract(4 个测试) |
✅ 全部通过 |
cargo check -p axvm --tests |
✅ 通过 |
cargo xtask axvisor build --arch x86_64 |
✅ 通过 |
cargo xtask axvisor build --arch aarch64 |
✅ 通过 |
cargo xtask axvisor build --arch riscv64 |
✅ 通过 |
cargo xtask axvisor build --arch loongarch64 |
✅ 通过(6 个 warning 为基础分支已存在的预存 warning) |
[patch.crates-io] 检查 |
✅ 未引入任何 crates.io patch |
axvm/src/ 中 ax_errno 残留引用 |
✅ 零引用 |
错误契约测试
tests/error_contract.rs 包含 4 个测试:
axvm_owns_its_public_error_contract— 验证 Cargo.toml 不含ax-errno,含thiserror;lib.rs 导出AxVmError/AxVmResult;error.rs 使用thiserror::Erroraxvm_sources_do_not_name_axerrno— 扫描所有 axvm/src/ 下的.rs文件,确保无ax_errno字符串public_failure_interfaces_name_axvm_result— 验证 runtime、vm、prepare、boot 模块的公共接口返回AxVmResultaxvisor_uses_anyhow_without_axerrno— 验证 axvisor 不再依赖ax-errno,使用anyhow并正确引用AxVmError::Boot
这些测试可以有效防止后续修改中重新引入旧依赖。
CI 状态
PR head b735af47 的 GitHub Actions check runs 全部为 skipped(路径过滤后的预期行为,此 PR 仅影响 virtualization/axvm/ 和 os/axvisor/ 目录)。本地已覆盖作者声明的所有验证命令。
重复/重叠 PR 分析
搜索 repo:rcore-os/tgoskits type:pr state:open axvm error 未发现与此 PR 重复或冲突的开放 PR。PR #1562(refactor(axvm): consolidate architecture-specific code)已合入 base,本 PR 基于该重构之上进一步改进错误处理,方向互补。
遗留问题
- LoongArch64 构建产生的 6 个 warning(
with_vm、active_vcpu_mask、inject_interrupt未使用,3 个 lint expectation 未满足)为基础分支已存在的预存问题,非本 PR 引入。 axvm-typescrate 的VmArchVcpuOps/VmArchPerCpuOpstrait 仍使用ax_errno类型别名,这是 PR 设计中有意保留的共享组件边界,建议后续独立 PR 中一并迁移。
Powered by deepseek-v4-pro
There was a problem hiding this comment.
审查结论:APPROVE
PR 概述
本 PR 在 axvm crate 中引入基于 thiserror 的 AxVmError / AxVmResult 领域错误类型,覆盖配置、输入、状态、生命周期、资源、Boot、Memory、Device、Vcpu、Interrupt 和 Host 等领域。同时删除旧的 VmLifecycleError 和 axvm 对 ax-errno 的依赖,并将 AxVisor 应用层迁移到 anyhow。新增错误契约测试防止回归。
实现逻辑
- AxVM 作为库 crate 提供可匹配的领域错误,通过
thiserror派生Error,符合book/guideline/code-quality.md第 5.3 节规范。 - 共享虚拟化组件(如
axvm-types)仍保留ax-errno契约,在 axvm 私有适配层按语境转换为领域错误,不提供全局From<AxError>。 - AxVisor 作为最终应用使用
anyhow聚合领域错误和应用层上下文,为 VM ID、配置阶段和镜像路径补充with_context。 ax_err_type!/ax_err!宏在内部保持兼容性,将旧的 errno 变体映射到新领域错误,module_path!()使用合理。Machine状态机通过AxVmError::invalid_transition()守卫不合法转换,生命周期行为不变。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check |
✅ 通过 |
cargo clippy -p axvm -- -D warnings |
✅ 通过 |
cargo test -p axvm(22 个测试) |
✅ 全部通过 |
错误契约测试(tests/error_contract.rs) |
✅ 4/4 通过 |
| CI: fmt / clippy / sync-lint / spin-lint | ✅ 全部通过 |
| CI: std 测试 | ✅ 通过(47/47) |
| CI: Starry QEMU(x86_64 / aarch64 / riscv64) | ✅ 全部通过 |
| CI: ArceOS QEMU(x86_64 / riscv64) | ✅ 全部通过 |
CI 中被跳过的 job(如 axvisor QEMU、self-hosted board 等)属于正常的路径过滤行为:该 PR 未改动这些 workflow 的过滤路径,且相关的基本构建验证(sync-lint 等)已覆盖。
crates.io patch 检查
未引入任何 [patch.crates-io] 覆盖。
重复/重叠 PR 分析
搜索 repo:rcore-os/tgoskits type:pr axvm error domain 仅返回本 PR #1590 和一个无关的 Starry 自编译 PR #1076。未发现重复、重叠或冲突的开放 PR。base 分支当前也无等效实现。
审查意见
该 PR 设计合理、实现完整,遵循项目编码规范:
- 库 crate 使用
thiserror定义具体错误类型 ✅ - 应用层使用
anyhow聚合错误 ✅ - 错误契约通过编译期/文件级测试守卫 ✅
- 无
[patch.crates-io]引入 ✅ - VM 生命周期状态机不变 ✅
- 格式化、clippy、测试均通过 ✅
无阻塞问题,批准合并。
Powered by deepseek-v4-pro
问题
AxVM 目前直接依赖
ax-errno,公共接口使用通用 errno,导致 AxVisor 无法按 VM 生命周期、内存、设备、vCPU、IRQ 或宿主能力区分错误,也会在应用层丢失配置阶段、VM ID 和镜像路径等诊断上下文。修改
axvm中新增基于thiserror的AxVmError和AxVmResult,覆盖配置、输入、状态、生命周期、资源、Boot、Memory、Device、Vcpu、Interrupt 和 Host 等领域错误。VmLifecycleError及axvm对ax-errno的依赖,公共失败接口统一返回AxVmResult。AxError,不提供无上下文的全局From<AxError>。anyhow,为 VM ID、配置阶段和镜像路径补充上下文;BootImageProvider 文件错误转换为 Boot 领域错误。ax_errno或旧结果接口。实现逻辑
AxVM 负责提供可匹配、稳定的领域错误;仍使用 errno 的共享虚拟化组件维持现有契约,由最靠近调用点的私有适配层根据语境转换。AxVisor 作为最终应用使用
anyhow聚合这些领域错误和应用层上下文,并通过完整错误链输出具体原因。VM 生命周期和批量启动容错行为保持不变。VM ID 查找统一经过私有适配函数,并使用纯错误构造函数生成
VmNotFound。回归测试直接验证错误构造,不保留AxVMRef的析构胶水,因此普通宿主测试无需链接 ArceOS 裸机运行时。验证
cargo fmt --allcargo test -p axvm(96 个单元测试、22 个集成测试全部通过)cargo xtask test(std 测试 47/47 通过)cargo xtask clippy --package axvm(6/6 通过)cargo xtask axvisor build --arch x86_64cargo xtask axvisor build --arch aarch64cargo xtask axvisor build --arch riscv64cargo xtask axvisor build --arch loongarch64cargo xtask axvisor test qemu --arch x86_64 --test-group normal(SVM、VMX 2/2 通过)