1
use std::sync::Arc;
2

            
3
use bonsaidb_core::{permissions::PermissionDenied, schema, schema::InsertError, AnyError};
4
use schema::InvalidNameError;
5

            
6
/// An error occurred while interacting with a [`Server`](crate::Server).
7
13
#[derive(Debug, thiserror::Error)]
8
pub enum Error {
9
    /// An error occurred from the QUIC transport layer.
10
    #[error("a networking error occurred: '{0}'")]
11
    Transport(String),
12

            
13
    #[cfg(feature = "websockets")]
14
    /// An error occurred from the Websocket transport layer.
15
    #[error("a websocket error occurred: '{0}'")]
16
    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
17

            
18
    /// An error occurred from IO
19
    #[error("a networking error occurred: '{0}'")]
20
    Io(#[from] tokio::io::Error),
21

            
22
    /// An error occurred while processing a request
23
    #[error("an error occurred processing a request: '{0}'")]
24
    Request(Arc<dyn AnyError>),
25

            
26
    /// An error occurred from within the schema.
27
    #[error("error from core {0}")]
28
    Core(#[from] bonsaidb_core::Error),
29

            
30
    /// An internal error occurred while waiting for a message.
31
    #[error("error while waiting for a message")]
32
    InternalCommunication,
33

            
34
    /// An error occurred while interacting with a local database.
35
    #[error("an error occurred interacting with a database: {0}")]
36
    Database(#[from] bonsaidb_local::Error),
37

            
38
    /// An error occurred with a certificate.
39
    #[error("a certificate error: {0}")]
40
    Certificate(#[from] fabruic::error::Certificate),
41

            
42
    /// An error occurred parsing a PEM file.
43
    #[error("an invalid PEM file: {0}")]
44
    #[cfg(feature = "pem")]
45
    Pem(#[from] pem::PemError),
46

            
47
    /// An error occurred requesting an ACME certificate.
48
    #[error("an error requesting an ACME certificate: {0}")]
49
    #[cfg(feature = "acme")]
50
    Acme(#[from] async_acme::acme::AcmeError),
51

            
52
    /// An error occurred while processing an ACME order.
53
    #[error("an error occurred while processing an ACME order: {0}")]
54
    #[cfg(feature = "acme")]
55
    AcmeOrder(#[from] async_acme::rustls_helper::OrderError),
56

            
57
    /// An error occurred during tls signing.
58
    #[error("an error occurred during tls signing")]
59
    TlsSigningError,
60
}
61

            
62
impl From<Error> for bonsaidb_core::Error {
63
    fn from(other: Error) -> Self {
64
        // without it, there's no way to get this to_string() easily.
65
        match other {
66
7241
            Error::Core(core) | Error::Database(bonsaidb_local::Error::Core(core)) => core,
67
            Error::Database(storage) => Self::Database(storage.to_string()),
68
            Error::Io(io) => Self::Io(io.to_string()),
69
            Error::Transport(networking) => Self::Transport(networking),
70
            #[cfg(feature = "websockets")]
71
            Error::WebSocket(err) => Self::Websocket(err.to_string()),
72
            err => Self::Server(err.to_string()),
73
        }
74
7241
    }
75
}
76

            
77
impl From<flume::RecvError> for Error {
78
    fn from(_: flume::RecvError) -> Self {
79
        Self::InternalCommunication
80
    }
81
}
82

            
83
impl<T> From<flume::SendError<T>> for Error {
84
    fn from(_: flume::SendError<T>) -> Self {
85
        Self::InternalCommunication
86
    }
87
}
88

            
89
impl From<tokio::sync::oneshot::error::RecvError> for Error {
90
    fn from(_: tokio::sync::oneshot::error::RecvError) -> Self {
91
        Self::InternalCommunication
92
    }
93
}
94

            
95
impl From<tokio::sync::oneshot::error::TryRecvError> for Error {
96
    fn from(_: tokio::sync::oneshot::error::TryRecvError) -> Self {
97
        Self::InternalCommunication
98
    }
99
}
100

            
101
impl From<PermissionDenied> for Error {
102
    fn from(err: PermissionDenied) -> Self {
103
        Self::Core(bonsaidb_core::Error::PermissionDenied(err))
104
    }
105
}
106

            
107
impl From<InvalidNameError> for Error {
108
    fn from(err: InvalidNameError) -> Self {
109
        Self::Core(bonsaidb_core::Error::InvalidName(err))
110
    }
111
}
112

            
113
impl From<rustls::sign::SignError> for Error {
114
    fn from(_: rustls::sign::SignError) -> Self {
115
        Self::TlsSigningError
116
    }
117
}
118

            
119
impl<T> From<InsertError<T>> for Error {
120
    fn from(error: InsertError<T>) -> Self {
121
        Self::from(error.error)
122
    }
123
}
124

            
125
pub trait ResultExt<R> {
126
    fn map_err_to_core(self) -> Result<R, bonsaidb_core::Error>
127
    where
128
        Self: Sized;
129
}
130

            
131
impl<R> ResultExt<R> for Result<R, Error> {
132
    fn map_err_to_core(self) -> Result<R, bonsaidb_core::Error>
133
    where
134
        Self: Sized,
135
    {
136
        self.map_err(bonsaidb_core::Error::from)
137
    }
138
}
139
impl From<pot::Error> for Error {
140
    fn from(other: pot::Error) -> Self {
141
        Self::Core(bonsaidb_core::Error::from(other))
142
    }
143
}
144

            
145
#[cfg(feature = "websockets")]
146
impl From<bincode::Error> for Error {
147
    fn from(other: bincode::Error) -> Self {
148
        Self::Core(bonsaidb_core::Error::Websocket(format!(
149
            "error deserializing message: {:?}",
150
            other
151
        )))
152
    }
153
}
154

            
155
macro_rules! impl_from_fabruic {
156
    ($error:ty) => {
157
        impl From<$error> for Error {
158
            fn from(other: $error) -> Self {
159
                Self::Core(bonsaidb_core::Error::Transport(other.to_string()))
160
            }
161
        }
162
    };
163
}
164

            
165
impl_from_fabruic!(fabruic::error::CertificateChain);
166
impl_from_fabruic!(fabruic::error::Receiver);
167
impl_from_fabruic!(fabruic::error::Connecting);
168
impl_from_fabruic!(fabruic::error::PrivateKey);
169
impl_from_fabruic!(fabruic::error::KeyPair);
170
impl_from_fabruic!(fabruic::error::Connection);
171
impl_from_fabruic!(fabruic::error::Incoming);
172
impl_from_fabruic!(fabruic::error::AlreadyClosed);
173
impl_from_fabruic!(fabruic::error::Config);