common_meta/error/retry_hint/
etcd.rs1use common_error::ext::{RetryHint, retry_hint_from_io_error};
16
17pub fn retry_hint_from_etcd_error(error: &etcd_client::Error) -> RetryHint {
19 match error {
20 etcd_client::Error::IoError(error) => retry_hint_from_io_error(error),
21 etcd_client::Error::TransportError(_)
22 | etcd_client::Error::EndpointError(_)
23 | etcd_client::Error::WatchError(_)
24 | etcd_client::Error::LeaseKeepAliveError(_)
25 | etcd_client::Error::ElectError(_) => RetryHint::Retryable,
26 etcd_client::Error::GRpcStatus(status) => retry_hint_from_etcd_grpc_code(status.code()),
27 etcd_client::Error::InvalidArgs(_)
28 | etcd_client::Error::InvalidUri(_)
29 | etcd_client::Error::Utf8Error(_)
30 | etcd_client::Error::InvalidHeaderValue(_)
31 | etcd_client::Error::EndpointsNotManaged => RetryHint::NonRetryable,
32 }
33}
34
35fn retry_hint_from_etcd_grpc_code(code: tonic::Code) -> RetryHint {
37 match code {
38 tonic::Code::Unavailable | tonic::Code::DeadlineExceeded | tonic::Code::Aborted => {
39 RetryHint::Retryable
40 }
41 _ => RetryHint::NonRetryable,
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use common_error::ext::RetryHint;
48
49 use super::*;
50
51 #[test]
52 fn test_etcd_grpc_status_retry_hint() {
53 assert_eq!(
54 retry_hint_from_etcd_grpc_code(tonic::Code::Unavailable),
55 RetryHint::Retryable
56 );
57 assert_eq!(
58 retry_hint_from_etcd_grpc_code(tonic::Code::DeadlineExceeded),
59 RetryHint::Retryable
60 );
61 assert_eq!(
62 retry_hint_from_etcd_grpc_code(tonic::Code::Aborted),
63 RetryHint::Retryable
64 );
65 assert_eq!(
66 retry_hint_from_etcd_grpc_code(tonic::Code::ResourceExhausted),
67 RetryHint::NonRetryable
68 );
69 assert_eq!(
70 retry_hint_from_etcd_grpc_code(tonic::Code::InvalidArgument),
71 RetryHint::NonRetryable
72 );
73 }
74}