tor_dirserver/
err.rs

1//! Error module for `tor-dirserver`.
2
3use deadpool::managed::PoolError;
4use thiserror::Error;
5use void::Void;
6
7/// An error while interacting with a database.
8///
9/// This error should be returned by all functions that interact with the
10/// database in one way or another.  Primarily, it wraps errors from crates such
11/// as [`rusqlite`], [`deadpool`], and [`deadpool_sqlite`]
12#[derive(Debug, Error)]
13#[non_exhaustive]
14pub(crate) enum DatabaseError {
15    /// A low-level SQLite error has occurred, which can have a bascially
16    /// infinite amount of reasons, all of them outlined in the actual SQLite
17    /// and [`rusqlite`] documentation.
18    #[error("low-level rusqlite error: {0}")]
19    LowLevel(#[from] rusqlite::Error),
20
21    /// This is an application level error meaning that the database can be
22    /// successfully accessed but its content implies it is of a schema version
23    /// we do not support.
24    ///
25    /// Keep in mind that an unrecognized schema is not equal to no schema.
26    /// In the latter case we actually initialize the database, whereas in the
27    /// previous one, we fail early in order to not corrupt an existing database.
28    /// Future versions of this crate should continue with this promise in order
29    /// to ensure forward compatability.
30    #[error("incompatible schema version: {version}")]
31    IncompatibleSchema {
32        /// The incompatible schema version found in the database.
33        version: String,
34    },
35
36    /// Interaction with our database pool, [`deadpool`], has failed.
37    ///
38    /// This error is only constructed by **some** error-variants of [`PoolError`].
39    /// In general, this application handles [`PoolError`] types as follows:
40    /// * [`PoolError::Backend`] is mapped to [`DatabaseError::LowLevel`].
41    /// * [`PoolError::PostCreateHook`] is mapped to [`DatabaseError::Bug`].
42    /// * Everything else is mapped to [`DatabaseError::Pool`].
43    ///
44    /// The motivation for this is, that [`PoolError::Backend`] and
45    /// [`PoolError::PostCreateHook`] contain [`rusqlite::Error`] as their
46    /// generic argument in the way we use it across the code base.  However,
47    /// for handling [`PoolError::Backend`], we already have
48    /// [`DatabaseError::LowLevel`], which exists to indicate underlying issues
49    /// with the database driver.  For handling [`PoolError::PostCreateHook`],
50    /// we opt for going with [`DatabaseError::Bug`], as we do not make use of
51    /// any post create hooks.
52    #[error("pool error: {0}")]
53    Pool(#[from] PoolError<Void>),
54
55    /// An internal error.
56    #[error("Internal error")]
57    Bug(#[from] tor_error::Bug),
58}