Mirror of https://github.com/roostorg/osprey
github.com/roostorg/osprey
1use etcd::kv::{self, WatchError};
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5pub enum EtcdError {
6 #[error("API error. index={} error={}", index, error)]
7 API { index: u64, error: etcd::Error },
8 #[error("Key not found. index={} error={}", index, error)]
9 KeyNotFound { index: u64, error: etcd::Error },
10 #[error("Key already exists. index={} error={}", index, error)]
11 KeyAlreadyExists { index: u64, error: etcd::Error },
12 #[error("Watch error. error={}", error)]
13 Watch { error: kv::WatchError },
14 #[error("Serialization error. error={}", error)]
15 Serialize { error: anyhow::Error },
16 #[error("The response had no index.")]
17 NoIndex,
18 #[error("IoError. error={}", error)]
19 IoError {
20 #[from]
21 error: std::io::Error,
22 },
23 #[error("Etcd error. error={}", error)]
24 Unknown { error: etcd::Error },
25}
26
27impl EtcdError {
28 pub fn index(&self) -> u64 {
29 match self {
30 EtcdError::API { index, .. } => *index,
31 _ => 0,
32 }
33 }
34}
35
36impl From<Vec<etcd::Error>> for EtcdError {
37 fn from(errors: Vec<etcd::Error>) -> EtcdError {
38 let error = errors
39 .into_iter()
40 .next()
41 .expect("invariant: errors must not be empty");
42
43 match error {
44 etcd::Error::Api(error) => {
45 if error.error_code == 100 {
46 EtcdError::KeyNotFound {
47 index: error.index,
48 error: etcd::Error::Api(error),
49 }
50 } else if error.error_code == 105 {
51 EtcdError::KeyAlreadyExists {
52 index: error.index,
53 error: etcd::Error::Api(error),
54 }
55 } else {
56 EtcdError::API {
57 index: error.index,
58 error: etcd::Error::Api(error),
59 }
60 }
61 }
62 other => EtcdError::Unknown { error: other },
63 }
64 }
65}
66
67impl From<kv::WatchError> for EtcdError {
68 fn from(error: WatchError) -> EtcdError {
69 match error {
70 WatchError::Other(errors) => EtcdError::from(errors),
71 error => EtcdError::Watch { error },
72 }
73 }
74}