Skip to main content

olai_stack_state/
error.rs

1//! The crate's [`Error`].
2
3/// What can go wrong reading or writing the [`Store`](crate::Store).
4#[derive(Debug, thiserror::Error)]
5pub enum Error {
6    /// SQLite failed.
7    #[error("state store: {0}")]
8    Sqlite(#[from] rusqlite::Error),
9    /// The store was written by a newer version than this one understands.
10    #[error(
11        "state store schema version {found} is newer than this version supports ({supported}); \
12         upgrade trestle"
13    )]
14    UnsupportedVersion {
15        /// The store's schema version.
16        found: u32,
17        /// The newest version this crate reads.
18        supported: u32,
19    },
20    /// A name is not valid (see [`is_valid_name`](olai_stack_topology::workspace::is_valid_name)).
21    #[error(
22        "`{0}` is not a valid name: use lowercase letters, digits and dashes, starting with a letter"
23    )]
24    InvalidName(String),
25    /// Something already exists under that name.
26    #[error("{kind} `{name}` already exists")]
27    Duplicate {
28        /// What kind of thing (`workspace`, `environment`).
29        kind: &'static str,
30        /// Its name.
31        name: String,
32    },
33    /// No such thing.
34    #[error("no {kind} `{id}`")]
35    NotFound {
36        /// What kind of thing.
37        kind: &'static str,
38        /// Its id or name.
39        id: String,
40    },
41    /// A workspace or environment can't be renamed (or its mesh changed) while it has
42    /// instances: their compose projects, volumes, hostnames and mesh network are named after
43    /// it, so the change would strand what Docker already holds under the old name.
44    #[error(
45        "{kind} `{name}` has {instances} instance{}: remove {} first",
46        if *instances == 1 { "" } else { "s" },
47        if *instances == 1 { "it" } else { "them" }
48    )]
49    HasInstances {
50        /// What kind of thing (`workspace`, `environment`).
51        kind: &'static str,
52        /// Its name.
53        name: String,
54        /// How many instances it has.
55        instances: usize,
56    },
57    /// Every slot is leased.
58    #[error("no free slot: the host runs at most {} instances", olai_stack_topology::MAX_SLOT + 1)]
59    SlotsExhausted,
60    /// An environment manifest didn't (de)serialize.
61    #[error(transparent)]
62    Manifest(#[from] olai_stack_topology::ManifestError),
63    /// A workspace manifest didn't (de)serialize.
64    #[error(transparent)]
65    Workspace(#[from] olai_stack_topology::WorkspaceError),
66    /// A stored JSON column didn't (de)serialize.
67    #[error("state store JSON: {0}")]
68    Json(#[from] serde_json::Error),
69    /// Reading or writing an import/export directory failed.
70    #[error("{path}: {source}")]
71    Io {
72        /// The file or directory.
73        path: std::path::PathBuf,
74        /// The I/O error.
75        #[source]
76        source: std::io::Error,
77    },
78    /// An export can't be written as asked.
79    #[error("can't export: {0}")]
80    Export(String),
81}
82
83impl Error {
84    pub(crate) fn io(path: impl Into<std::path::PathBuf>, source: std::io::Error) -> Self {
85        Error::Io {
86            path: path.into(),
87            source,
88        }
89    }
90}
91
92/// The crate's result type.
93pub type Result<T, E = Error> = std::result::Result<T, E>;