1
use bonsaidb_core::custom_api::CustomApiError;
2

            
3
/// Errors related to working with [`Client`](crate::Client)
4
4
#[derive(thiserror::Error, Debug)]
5
pub enum Error<ApiError: CustomApiError> {
6
    #[cfg(feature = "websockets")]
7
    /// An error occurred from the WebSocket transport layer.
8
    #[error("a transport error occurred: '{0}'")]
9
    WebSocket(crate::client::WebSocketError),
10

            
11
    /// An error occurred from networking.
12
    #[error("a networking error occurred: '{0}'")]
13
    Network(#[from] bonsaidb_core::networking::Error),
14

            
15
    /// An invalid Url was provided.
16
    #[error("invalid url: '{0}'")]
17
    InvalidUrl(String),
18

            
19
    /// The connection was interrupted.
20
    #[error("unexpected disconnection")]
21
    Disconnected,
22

            
23
    /// The connection was interrupted.
24
    #[error("unexpected disconnection")]
25
    Core(#[from] bonsaidb_core::Error),
26

            
27
    /// An error from the custom API.
28
    #[error("api error: {0}")]
29
    Api(ApiError),
30

            
31
    /// The server is incompatible with this version of the client.
32
    #[error("server incompatible with client protocol version")]
33
    ProtocolVersionMismatch,
34
}
35

            
36
impl<T, ApiError: CustomApiError> From<flume::SendError<T>> for Error<ApiError> {
37
    fn from(_: flume::SendError<T>) -> Self {
38
        Self::Disconnected
39
    }
40
}
41

            
42
impl<ApiError: CustomApiError> From<flume::RecvError> for Error<ApiError> {
43
    fn from(_: flume::RecvError) -> Self {
44
        Self::Disconnected
45
    }
46
}
47

            
48
impl<ApiError: CustomApiError> From<Error<ApiError>> for bonsaidb_core::Error {
49
2
    fn from(other: Error<ApiError>) -> Self {
50
2
        match other {
51
            Error::Core(err) => err,
52
2
            other => Self::Client(other.to_string()),
53
        }
54
2
    }
55
}
56

            
57
#[cfg(feature = "websockets")]
58
impl<ApiError: CustomApiError> From<bincode::Error> for Error<ApiError> {
59
    fn from(other: bincode::Error) -> Self {
60
        Self::Core(bonsaidb_core::Error::Websocket(format!(
61
            "error decoding websocket message: {:?}",
62
            other
63
        )))
64
    }
65
}
66

            
67
#[cfg(not(target_arch = "wasm32"))]
68
mod fabruic_impls {
69
    macro_rules! impl_from_fabruic {
70
        ($error:ty) => {
71
            impl<ApiError: bonsaidb_core::custom_api::CustomApiError> From<$error>
72
                for $crate::Error<ApiError>
73
            {
74
16
                fn from(other: $error) -> Self {
75
16
                    Self::Core(bonsaidb_core::Error::Transport(other.to_string()))
76
16
                }
77
            }
78
        };
79
    }
80

            
81
    impl_from_fabruic!(fabruic::error::Sender);
82
    impl_from_fabruic!(fabruic::error::Receiver);
83
    impl_from_fabruic!(fabruic::error::Stream);
84
    impl_from_fabruic!(fabruic::error::Connecting);
85
    impl_from_fabruic!(fabruic::error::Connect);
86
}
87

            
88
#[cfg(feature = "websockets")]
89
impl<ApiError: CustomApiError> From<crate::client::WebSocketError> for Error<ApiError> {
90
    #[cfg(not(target_arch = "wasm32"))]
91
    fn from(err: crate::client::WebSocketError) -> Self {
92
3
        if let crate::client::WebSocketError::Http(response) = &err {
93
1
            if response.status() == 406 {
94
1
                return Self::ProtocolVersionMismatch;
95
            }
96
2
        }
97

            
98
2
        Self::WebSocket(err)
99
3
    }
100

            
101
    #[cfg(target_arch = "wasm32")]
102
    fn from(err: crate::client::WebSocketError) -> Self {
103
        Self::WebSocket(err)
104
    }
105
}