plugmem_host/error.rs
1//! Host-layer errors.
2
3use std::path::PathBuf;
4
5/// Every way the host layer can fail. Engine failures pass through as
6/// [`HostError::Engine`]; everything filesystem- or network-shaped is
7/// typed here.
8#[derive(Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum HostError {
11 /// The database file is exclusively locked by another process (or
12 /// another handle in this process). One file has one owner — open a
13 /// different file, or drop the other handle.
14 #[error("database at {} is locked by another process", path.display())]
15 Locked {
16 /// The database base path.
17 path: PathBuf,
18 },
19
20 /// A filesystem operation failed.
21 #[error("i/o on {}: {source}", path.display())]
22 Io {
23 /// The file the operation touched.
24 path: PathBuf,
25 /// The underlying error.
26 #[source]
27 source: std::io::Error,
28 },
29
30 /// A read-only open ([`crate::Database::open_readonly`]) found a
31 /// non-empty journal. Replaying it would mutate the engine — copying
32 /// whole arenas up from the mapped bytes (copy-on-write) — which
33 /// defeats the zero-copy intent. Open the database read-write once to
34 /// checkpoint it (fold the journal into the snapshot), then retry
35 #[error("database at {} needs a checkpoint before a read-only open (non-empty journal)", path.display())]
36 NeedsCheckpoint {
37 /// The database base path.
38 path: PathBuf,
39 },
40
41 /// The engine returned a typed error.
42 #[error(transparent)]
43 Engine(#[from] plugmem_core::Error),
44
45 /// The embedder transport or response was unusable (the message
46 /// names what exactly: status, dimension mismatch, malformed JSON).
47 #[error("embedder: {0}")]
48 Embed(String),
49}
50
51impl HostError {
52 /// Shorthand for wrapping an I/O error with its path.
53 pub(crate) fn io(path: &std::path::Path, source: std::io::Error) -> Self {
54 Self::Io {
55 path: path.to_path_buf(),
56 source,
57 }
58 }
59}