1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use static_assertions::assert_impl_all;
use thiserror::Error;

/// Errors for ZooKeeper operations.
#[non_exhaustive]
#[derive(Error, Clone, Debug, PartialEq, Eq)]
pub enum Error {
    #[error("unable to unmarshal {entity} due to {reason}")]
    UnmarshalError { entity: &'static str, reason: &'static &'static str },

    #[error("no available hosts")]
    NoHosts,

    #[error("timeout")]
    Timeout,

    #[error("unexpected error: {0}")]
    UnexpectedError(String),

    #[error("bad arguments: {0}")]
    BadArguments(&'static &'static str),

    #[error("node not exists")]
    NoNode,

    #[error("not authorized")]
    NoAuth,

    #[error("mismatch version")]
    BadVersion,

    #[error("ephemeral node can not have children")]
    NoChildrenForEphemerals,

    #[error("node already exists")]
    NodeExists,

    #[error("node has not empty children")]
    NotEmpty,

    #[error("session expired")]
    SessionExpired,

    #[error("invalid acls")]
    InvalidAcl,

    #[error("authentication failed")]
    AuthFailed,

    #[error("session moved")]
    SessionMoved,

    #[error("write request is sent to read only server")]
    NotReadOnly,

    #[error("no watcher")]
    NoWatcher,

    #[error("exceed path quota")]
    QuotaExceeded,

    #[error("request was throttled due to server heavy loading")]
    Throttled,

    #[error("server fail to marshal client request")]
    MarshallingError,

    #[error("unimplemented operation")]
    Unimplemented,

    #[error("connection to server has lost")]
    ConnectionLoss,

    #[error("ZooKeeper reconfiguration disabled")]
    ReconfigDisabled,

    #[error("unexpected error code: {0}")]
    UnexpectedErrorCode(i32),

    #[error("client has been closed")]
    ClientClosed,

    #[error("runtime condition mismatch")]
    RuntimeInconsistent,
}

impl Error {
    pub(crate) fn has_no_data_change(&self) -> bool {
        match self {
            Self::NoNode
            | Self::NoAuth
            | Self::BadVersion
            | Self::NoChildrenForEphemerals
            | Self::NodeExists
            | Self::NotEmpty
            | Self::InvalidAcl
            | Self::AuthFailed
            | Self::SessionMoved
            | Self::NotReadOnly
            | Self::NoWatcher
            | Self::QuotaExceeded
            | Self::Throttled
            | Self::MarshallingError
            | Self::Unimplemented
            | Self::ReconfigDisabled
            | Self::UnexpectedErrorCode(_) => true,
            // We are expired anyway, any ephemeral nodes will be deleted by ZooKeeper soon.
            Self::SessionExpired => true,
            // We are closed anyway, the session will expire soon.
            Self::ClientClosed => true,
            _ => false,
        }
    }
}

assert_impl_all!(Error: Send, Sync);

impl From<std::convert::Infallible> for Error {
    fn from(_: std::convert::Infallible) -> Error {
        unreachable!();
    }
}