1use std::fmt::Display;
2use std::sync::Arc;
3
4use bonsaidb_core::permissions::PermissionDenied;
5use bonsaidb_core::schema::InsertError;
6use bonsaidb_core::{schema, AnyError};
7use schema::InvalidNameError;
8
9#[derive(Debug, thiserror::Error)]
11pub enum Error {
12 #[cfg(feature = "websockets")]
13 #[error("a websocket error occurred: '{0}'")]
15 WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
16
17 #[error("a networking error occurred: '{0}'")]
19 Io(#[from] tokio::io::Error),
20
21 #[error("an error occurred processing a request: '{0}'")]
23 Request(Arc<dyn AnyError>),
24
25 #[error("error from core {0}")]
27 Core(#[from] bonsaidb_core::Error),
28
29 #[error("error while waiting for a message")]
31 InternalCommunication,
32
33 #[error("an error occurred interacting with a database: {0}")]
35 Database(#[from] bonsaidb_local::Error),
36
37 #[error("a certificate error: {0}")]
39 Certificate(#[from] fabruic::error::Certificate),
40
41 #[error("an invalid PEM file: {0}")]
43 #[cfg(feature = "pem")]
44 Pem(#[from] pem::PemError),
45
46 #[error("an error requesting an ACME certificate: {0}")]
48 #[cfg(feature = "acme")]
49 Acme(#[from] async_acme::acme::AcmeError),
50
51 #[error("an error occurred while processing an ACME order: {0}")]
53 #[cfg(feature = "acme")]
54 AcmeOrder(#[from] async_acme::rustls_helper::OrderError),
55
56 #[error("an error occurred during tls signing")]
58 TlsSigningError,
59}
60
61impl Error {
62 pub(crate) fn other(origin: impl Display, error: impl Display) -> Self {
63 Self::Core(bonsaidb_core::Error::other(origin, error))
64 }
65}
66
67impl From<Error> for bonsaidb_core::Error {
68 fn from(other: Error) -> Self {
69 match other {
71 Error::Core(core) | Error::Database(bonsaidb_local::Error::Core(core)) => core,
72 Error::Database(storage) => Self::from(storage),
73 Error::Io(io) => Self::other("io", io),
74 #[cfg(feature = "websockets")]
75 Error::WebSocket(err) => Self::other("bonsaidb-server websockets", err),
76 err => Self::other("bonsaidb-server", err),
77 }
78 }
79}
80
81impl From<flume::RecvError> for Error {
82 fn from(_: flume::RecvError) -> Self {
83 Self::InternalCommunication
84 }
85}
86
87impl<T> From<flume::SendError<T>> for Error {
88 fn from(_: flume::SendError<T>) -> Self {
89 Self::InternalCommunication
90 }
91}
92
93impl From<tokio::sync::oneshot::error::RecvError> for Error {
94 fn from(_: tokio::sync::oneshot::error::RecvError) -> Self {
95 Self::InternalCommunication
96 }
97}
98
99impl From<tokio::sync::oneshot::error::TryRecvError> for Error {
100 fn from(_: tokio::sync::oneshot::error::TryRecvError) -> Self {
101 Self::InternalCommunication
102 }
103}
104
105impl From<PermissionDenied> for Error {
106 fn from(err: PermissionDenied) -> Self {
107 Self::Core(bonsaidb_core::Error::PermissionDenied(err))
108 }
109}
110
111impl From<InvalidNameError> for Error {
112 fn from(err: InvalidNameError) -> Self {
113 Self::Core(bonsaidb_core::Error::InvalidName(err))
114 }
115}
116
117impl From<rustls::sign::SignError> for Error {
118 fn from(_: rustls::sign::SignError) -> Self {
119 Self::TlsSigningError
120 }
121}
122
123impl<T> From<InsertError<T>> for Error {
124 fn from(error: InsertError<T>) -> Self {
125 Self::from(error.error)
126 }
127}
128
129pub trait ResultExt<R> {
130 fn map_err_to_core(self) -> Result<R, bonsaidb_core::Error>
131 where
132 Self: Sized;
133}
134
135impl<R> ResultExt<R> for Result<R, Error> {
136 fn map_err_to_core(self) -> Result<R, bonsaidb_core::Error>
137 where
138 Self: Sized,
139 {
140 self.map_err(bonsaidb_core::Error::from)
141 }
142}
143impl From<pot::Error> for Error {
144 fn from(other: pot::Error) -> Self {
145 Self::Core(bonsaidb_core::Error::from(other))
146 }
147}
148
149#[cfg(feature = "websockets")]
150impl From<bincode::Error> for Error {
151 fn from(other: bincode::Error) -> Self {
152 Self::Core(bonsaidb_core::Error::other("bincode", other))
153 }
154}
155
156macro_rules! impl_from_fabruic {
157 ($error:ty) => {
158 impl From<$error> for Error {
159 fn from(other: $error) -> Self {
160 Self::Core(bonsaidb_core::Error::other("bonsaidb-server quic", other))
161 }
162 }
163 };
164}
165
166impl_from_fabruic!(fabruic::error::CertificateChain);
167impl_from_fabruic!(fabruic::error::Receiver);
168impl_from_fabruic!(fabruic::error::Connecting);
169impl_from_fabruic!(fabruic::error::PrivateKey);
170impl_from_fabruic!(fabruic::error::KeyPair);
171impl_from_fabruic!(fabruic::error::Connection);
172impl_from_fabruic!(fabruic::error::Incoming);
173impl_from_fabruic!(fabruic::error::AlreadyClosed);
174impl_from_fabruic!(fabruic::error::Config);
175impl_from_fabruic!(fabruic::error::Builder);