故障排查
本页汇总 Dart 运行时中常见的问题及其修复方式。
Only xlang payloads are supported by the Dart runtime.
写端发送的是 native-mode(非 xlang)载荷。请确保每个服务都走跨语言兼容路径:
- Java:在 Fory builder 上添加
.withLanguage(Language.XLANG)。 - Go:在 Fory 选项中使用
WithXlang(true)。 - 其他运行时:查看各自文档,确认如何启用跨语言模式。
Type ... is not registered.
Fory 不知道如何序列化或反序列化这个类型。可按以下方式修复:
- 如果还没生成代码,先运行:
dart run build_runner build --delete-conflicting-outputs - 在调用
serialize或deserialize之前,先调用生成的register函数,或者registerSerializer - 注册消息中可能出现的所有类型,而不仅仅是根类型。例如,如果
Order包含Address,那两者都要注册
生成的 part 文件缺失或已过期
重新生成代码:
cd dart/packages/fory
dart run build_runner build --delete-conflicting-outputs
如果你移动了文件或重命名了类型,请在重新执行分析或测试前先重新构建。
Deserialized value has type ..., expected ...
载荷描述的类型与 deserialize<T> 中的 T 不一致。常见原因包括:
- 写端注册该类型时使用的 ID 或名称,与读端不一致
- 载荷来自另一条代码路径,根对象类型不同
- 你正在反序列化异构容器。应先按
Object?或List<Object?>解码,再做类型转换
反序列化后对象不再是同一个实例
默认情况下,Fory 不会跟踪对象标识,因此两个字段如果指向同一个对象,round trip 后会变成两个独立副本。
如果需要保留对象标识:
- 对
@ForyStruct内部字段,在对应字段上加@ForyField(ref: true) - 对顶层集合,调用
fory.serialize(...)时传入trackRef: true - 在自定义序列化器中,使用
context.writeRef/context.readRef,并在读取嵌套字段之前先调用context.reference(obj)
跨语言字段不匹配(数据缺失或值错误)
典型症状:往返另一种语言后,字段变成默认值,或者类型错误。
检查清单:
- 双方使用相同的注册身份,即相同数字 ID,或相同的
namespace + typeName - 在第一份载荷发送前,就已经分配了稳定
@ForyField(id: ...) - 数字宽度兼容。当对端字段是 Java
int、Goint32或 C#int时,在 Dart 端使用Int32 - 日期时间字段使用
Timestamp/LocalDate,而不是原始DateTime - 如果用到 Schema 演进,则双方都要开启
compatible: true
本地运行测试
主 Dart 包:
dart run build_runner build --delete-conflicting-outputs
dart analyze
dart test
集成测试包:
cd dart/packages/fory-test
dart run build_runner build --delete-conflicting-outputs
dart test