fix(meta): preserve legacy retry hints in instruction replies

Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
WenyXu
2026-10-12 12:02:04 +00:00
parent 3c5f505bd4
commit bbfa89d451
+33 -1
View File
@@ -49,7 +49,7 @@ pub struct InstructionError {
pub message: String,
/// Retry hint serialized as a string.
#[serde(
serialize_with = "RetryHint::serialize_as_str",
serialize_with = "InstructionError::serialize_retry_hint",
deserialize_with = "RetryHint::deserialize_from_str"
)]
pub retry_hint: RetryHint,
@@ -108,6 +108,18 @@ impl InstructionError {
retry_hint: error.retry_hint(),
}
}
/// Keeps instruction replies readable by peers that only know the legacy hints.
fn serialize_retry_hint<S>(hint: &RetryHint, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let hint = match hint {
RetryHint::RetryAfterRouteRefresh => RetryHint::Retryable,
hint => *hint,
};
RetryHint::serialize_as_str(&hint, serializer)
}
}
impl Display for InstructionError {
@@ -1450,6 +1462,26 @@ mod tests {
);
}
#[test]
fn test_instruction_error_route_refresh_compatibility() {
let error = InstructionError::new(
StatusCode::RegionNotFound,
"region not found",
RetryHint::RetryAfterRouteRefresh,
);
let serialized = serde_json::to_string(&error).unwrap();
assert_eq!(
r#"{"code":4005,"message":"region not found","retry_hint":"retryable"}"#,
serialized
);
let decoded: InstructionError = serde_json::from_str(&serialized).unwrap();
assert_eq!(decoded.code, error.code);
assert_eq!(decoded.message, error.message);
assert_eq!(decoded.retry_hint, RetryHint::Retryable);
assert_eq!(error.retry_hint, RetryHint::RetryAfterRouteRefresh);
assert_eq!(error.retry_hint.as_str(), "retry_after_route_refresh");
}
#[test]
fn test_instruction_error_from_error() {
let error = MockError::new(StatusCode::RegionNotFound);