Troubleshooting
This page covers common issues and debugging techniques for Apache Fory™ Rust.
Common Issues
Type Registry Errors
Error: TypeId ... not found in type_info registry
Cause: The type was never registered with the current Fory instance.
Solution: Register the type before serialization:
let mut fory = Fory::default();
fory.register::<MyStruct>(100)?; // Register before use
Confirm that:
- Every concrete dynamic target is registered through the matching structural, union, or custom serializer API.
- The same ID or name mapping is reused on the deserialize side.
For external-type serialization, register the selected external structural or custom serializer, not its third-party target:
fory.register::<UserSerializer>(100)?;
Do not register VecSerializer<UserSerializer> or another carrier serializer.
Register UserSerializer, then use recursive list, map, or tuple
annotations at fields, or select the carrier serializer at a root.
Type Mismatch Errors
Cause: Field types are incompatible or schema has changed.
Solution:
- Keep compatible mode enabled for schema evolution
- Ensure field types match across versions
// Remove any compatible(false) override from the peers.
let fory = Fory::builder()
// existing options
.build();
External-Type Serialization Selection Errors
If derive reports that with targets the wrong type, verify that the selected
serializer declares the exact field target:
impl Serializer for UserSerializer {
type Target = third_party::User;
// ...
}
For a transparent holder, select the carrier serializer whose target is the exact field type:
#[fory(with = OptionSerializer<UserSerializer>)]
user: Option<third_party::User>
For an exact container field, a carrier serializer is also valid:
#[fory(with = VecSerializer<UserSerializer>)]
users: Vec<third_party::User>
Use recursive collection syntax when selecting an element, map child, or tuple position:
#[fory(list(element(with = UserSerializer)))]
users: Vec<third_party::User>
If registration fails only in xlang mode, check whether the external structural serializer contains a native Rust enum variant with multiple fields. That shape has no xlang UNION representation; use native mode or change the shared schema.
Debugging Techniques
Enable Panic on Error for Backtraces
Toggle FORY_PANIC_ON_ERROR=1 alongside RUST_BACKTRACE=1 to panic at the exact site an error is constructed:
RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 cargo test --features tests
Reset the variable afterwards to avoid aborting user-facing code paths.
Struct Field Tracing
Add the #[fory(debug)] attribute alongside #[derive(ForyStruct)] to emit hook invocations:
#[derive(ForyStruct)]
#[fory(debug)]
struct MyStruct {
field1: i32,
field2: String,
}
Once compiled with debug hooks, call these functions to plug in custom callbacks:
set_before_write_field_funcset_after_write_field_funcset_before_read_field_funcset_after_read_field_func
Use reset_struct_debug_hooks() when you want the defaults back.
Lightweight Logging
Without custom hooks, enable ENABLE_FORY_DEBUG_OUTPUT=1 to print field-level read/write events:
ENABLE_FORY_DEBUG_OUTPUT=1 cargo test --features tests
This is especially useful when investigating alignment or cursor mismatches.
Inspect Generated Code
Use cargo expand to inspect code generated by Fory derive macros:
cargo expand --test mod $mod$::$file$ > expanded.rs
Running Tests
Run All Tests
cargo test --features tests
Run Specific Test
cargo test -p tests --test $test_file $test_method
Run Test with Debugging
RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 ENABLE_FORY_DEBUG_OUTPUT=1 \
cargo test --test mod $dir$::$test_file::$test_method -- --nocapture
Test-Time Hygiene
Some integration tests expect FORY_PANIC_ON_ERROR to remain unset. Export it only for focused debugging sessions:
# For specific debugging only
FORY_PANIC_ON_ERROR=1 cargo test -p tests --test specific_test -- --nocapture
# Normal test run (without panic on error)
cargo test --features tests
Error Handling Best Practices
Prefer the static constructors on the facade Error type:
Error::type_mismatchError::invalid_dataError::unknown
This keeps diagnostics consistent and makes opt-in panics work correctly.
Quick Reference
| Environment Variable | Purpose |
|---|---|
RUST_BACKTRACE=1 | Enable stack traces |
FORY_PANIC_ON_ERROR=1 | Panic at error site for debugging |
ENABLE_FORY_DEBUG_OUTPUT=1 | Print field-level read/write events |
Related Topics
- Configuration - Fory options
- Type Registration - Registration best practices
- Schema Evolution - Compatible mode
- External-Type Serialization - Field and root serializer selection