santiagomed opened a new pull request, #3414:
URL: https://github.com/apache/thrift/pull/3414
## Problem
When a struct contains a union-typed field and the wire data has a union
variant (field ID) not present in the local IDL, the generated Rust code fails
to deserialize the **entire struct** — not just the unknown union field.
The root cause: the union`s `read_from_in_protocol` correctly returns
`Err("received empty union")` for unknown variants (fixed in THRIFT-5926 / PR
#3336). But the parent struct`s generated deserializer propagates this error
via `?`, causing the whole struct to fail.
This breaks Thrift`s forward-compatibility guarantee. When a server adds a
new union variant, all clients running an older IDL version fail to parse any
message containing that variant — even though the client doesn`t need to
understand the new variant to process the rest of the struct.
Java, Go, Python, and C++ Thrift all handle this gracefully: unknown union
variants are silently skipped, and the struct field is left unset.
## Fix
In `render_struct_sync_read`, detect struct fields whose type is a union.
For those fields, wrap the `read_from_in_protocol` call in a `match` that
catches the `"received empty union"` error and treats it as `None` (field
absent):
```rust
// Before (all fields):
let val = FooUnion::read_from_in_protocol(i_prot)?;
f_N = Some(val);
// After (union fields only):
match FooUnion::read_from_in_protocol(i_prot) {
Ok(val) => { f_N = Some(val); },
Err(thrift::Error::Protocol(ref e))
if e.message.contains("received empty union") => {
// forward compatibility: unknown union variant skipped
},
Err(e) => return Err(e),
}
```
Non-union fields are unchanged. The union`s own `TSerializable` impl is
unchanged — it still returns `Err` for unknown variants, preserving the
contract for callers that read unions directly.
## Impact
- Fixes forward compatibility for all Rust Thrift users with evolving union
schemas
- No changes to the `TSerializable` trait or the thrift runtime library
- No changes to the union`s own serialization/deserialization
- Struct fields with union types that receive unknown variants get `None`
instead of causing parse failure
- All other errors (malformed data, I/O, multiple union fields) still
propagate normally
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]