Skip to main content

post_cortex_storage/
error.rs

1// Copyright (c) 2025, 2026 Julius ML
2// Licensed under the MIT License. See LICENSE at the workspace root.
3
4//! Typed error hierarchy for `post-cortex-storage`.
5//!
6//! See the crate-level docs on `post-cortex-core::error` for the
7//! workspace-wide error policy. Storage errors carry source chains via
8//! `#[source]` so callers can pattern-match on the underlying RocksDB /
9//! SurrealDB cause.
10
11use thiserror::Error;
12
13/// Errors produced by storage backends.
14#[derive(Debug, Error)]
15pub enum Error {
16    /// RocksDB-layer error (transaction, write batch, iterator, column
17    /// family).
18    #[error("rocksdb error: {0}")]
19    RocksDb(#[from] rocksdb::Error),
20
21    /// SurrealDB error (kv-mem / kv-tikv / protocol-ws).
22    #[cfg(feature = "surrealdb-storage")]
23    #[error("surrealdb error: {0}")]
24    SurrealDb(String),
25
26    /// (De)serialization failure on a persisted record.
27    #[error("serialization error: {0}")]
28    Serialization(String),
29
30    /// Logical "not found" — referenced session / workspace / entity
31    /// missing from the backend.
32    #[error("not found: {kind} {id}")]
33    NotFound {
34        /// Kind of entity that was missing (e.g. `"session"`, `"workspace"`).
35        kind: &'static str,
36        /// Identifier of the missing entity.
37        id: String,
38    },
39
40    /// Export / import file format error (corrupt header, unsupported
41    /// version, compression failure).
42    #[error("export/import format error: {0}")]
43    Format(String),
44
45    /// I/O error from the underlying filesystem.
46    #[error("io error: {0}")]
47    Io(#[from] std::io::Error),
48
49    /// Catch-all for migrating call sites that still use `anyhow`.
50    #[error(transparent)]
51    External(#[from] anyhow::Error),
52}
53
54/// Crate-level result alias.
55pub type Result<T, E = Error> = std::result::Result<T, E>;
56
57// bincode 2 conversions
58impl From<bincode::error::EncodeError> for Error {
59    fn from(err: bincode::error::EncodeError) -> Self {
60        Self::Serialization(err.to_string())
61    }
62}
63
64impl From<bincode::error::DecodeError> for Error {
65    fn from(err: bincode::error::DecodeError) -> Self {
66        Self::Serialization(err.to_string())
67    }
68}
69
70impl Error {
71    /// A stable discriminant for metrics / structured logs.
72    #[must_use]
73    pub fn kind(&self) -> &'static str {
74        match self {
75            Self::RocksDb(_) => "rocksdb",
76            #[cfg(feature = "surrealdb-storage")]
77            Self::SurrealDb(_) => "surrealdb",
78            Self::Serialization(_) => "serialization",
79            Self::NotFound { .. } => "not_found",
80            Self::Format(_) => "format",
81            Self::Io(_) => "io",
82            Self::External(_) => "external",
83        }
84    }
85}