跳到主要内容
版本:1.5.0

故障排查

本页介绍 Apache Fory™ Rust 的常见问题和调试技巧。

常见问题

类型注册表错误

错误TypeId ... not found in type_info registry

原因:该类型从未在当前 Fory 实例中注册。

解决方案:在序列化之前注册类型:

let mut fory = Fory::default();
fory.register::<MyStruct>(100)?; // 使用前注册

请确认:

  • 每个动态具体目标都通过与之匹配的结构化序列化器、联合类型序列化器或自定义序列化器 API 注册。
  • 反序列化端复用了相同的 ID 或名称映射。

使用外部类型序列化时,应注册所选的外部结构化序列化器或自定义序列化器,而不是其第三方目标类型:

fory.register::<UserSerializer>(100)?;

不要注册 VecSerializer<UserSerializer> 或其他承载序列化器。请注册 UserSerializer,然后在字段上使用递归的 listmaptuple 注解,或者在根值上选择承载序列化器。

类型不匹配错误

原因:字段类型不兼容或 Schema 已变更。

解决方案

  • 保持兼容模式启用,以支持 Schema 演进
  • 确保跨版本字段类型匹配
// 从通信双方移除所有 compatible(false) 覆盖。
let fory = Fory::builder()
// 现有选项
.build();

外部类型序列化选择错误

如果派生宏报告 with 的目标类型错误,请确认所选序列化器声明了完全匹配的字段目标类型:

impl Serializer for UserSerializer {
type Target = third_party::User;
// ...
}

对于透明 holder,请选择目标类型与字段类型完全匹配的承载序列化器:

#[fory(with = OptionSerializer<UserSerializer>)]
user: Option<third_party::User>

对于完全匹配的容器字段,也可以使用承载序列化器:

#[fory(with = VecSerializer<UserSerializer>)]
users: Vec<third_party::User>

当选择元素、map 子节点或 tuple 位置时,请使用递归集合语法:

#[fory(list(element(with = UserSerializer)))]
users: Vec<third_party::User>

如果注册只在 xlang 模式下失败,请检查外部结构化序列化器是否包含带多个字段的 Rust native 枚举变体。这种结构没有对应的 xlang UNION 表示;请使用 native 模式,或修改共享 Schema。

调试技巧

在错误处 Panic 以获取回溯

FORY_PANIC_ON_ERROR=1RUST_BACKTRACE=1 一起启用,使程序在错误构造的确切位置 panic:

RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 cargo test --features tests

完成后重置该变量,以免面向用户的代码路径中止。

跟踪结构体字段

#[derive(ForyStruct)] 旁添加 #[fory(debug)] 属性,以发出 hook 调用:

#[derive(ForyStruct)]
#[fory(debug)]
struct MyStruct {
field1: i32,
field2: String,
}

使用调试 hook 编译后,调用以下函数接入自定义回调:

  • set_before_write_field_func
  • set_after_write_field_func
  • set_before_read_field_func
  • set_after_read_field_func

需要恢复默认值时,请使用 reset_struct_debug_hooks()

轻量级日志

不使用自定义 hook 时,可以启用 ENABLE_FORY_DEBUG_OUTPUT=1 来打印字段级读写事件:

ENABLE_FORY_DEBUG_OUTPUT=1 cargo test --features tests

这对于排查对齐或游标不匹配尤其有用。

检查生成的代码

使用 cargo expand 检查 Fory 派生宏生成的代码:

cargo expand --test mod $mod$::$file$ > expanded.rs

运行测试

运行所有测试

cargo test --features tests

运行指定测试

cargo test -p tests --test $test_file $test_method

在调试模式下运行测试

RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 ENABLE_FORY_DEBUG_OUTPUT=1 \
cargo test --test mod $dir$::$test_file::$test_method -- --nocapture

测试环境注意事项

部分集成测试要求 FORY_PANIC_ON_ERROR 保持未设置状态。仅在针对性调试会话中设置该变量:

# 仅用于指定的调试任务
FORY_PANIC_ON_ERROR=1 cargo test -p tests --test specific_test -- --nocapture

# 正常运行测试(不在错误处 panic)
cargo test --features tests

错误处理最佳实践

优先使用 facade Error 类型上的静态构造函数:

  • Error::type_mismatch
  • Error::invalid_data
  • Error::unknown

这样可以保持诊断一致,并确保按需启用的 panic 正常工作。

快速参考

环境变量用途
RUST_BACKTRACE=1启用堆栈跟踪
FORY_PANIC_ON_ERROR=1在错误位置 panic 以便调试
ENABLE_FORY_DEBUG_OUTPUT=1打印字段级读写事件

相关主题