Skip to main content

orcs_runtime/session/
error.rs

1//! Storage error types.
2
3use std::path::PathBuf;
4use thiserror::Error;
5
6/// Errors that can occur during session storage operations.
7#[derive(Debug, Error)]
8pub enum StorageError {
9    /// Session not found.
10    #[error("session not found: {0}")]
11    NotFound(String),
12
13    /// I/O error during file operations.
14    #[error("I/O error: {0}")]
15    Io(#[from] std::io::Error),
16
17    /// JSON serialization/deserialization error.
18    #[error("serialization error: {0}")]
19    Serialization(#[from] serde_json::Error),
20
21    /// Invalid path.
22    #[error("invalid path: {0}")]
23    InvalidPath(PathBuf),
24
25    /// Storage directory creation failed.
26    #[error("failed to create storage directory: {path}")]
27    DirectoryCreation {
28        path: PathBuf,
29        #[source]
30        source: std::io::Error,
31    },
32
33    /// Checksum mismatch (data corruption).
34    #[error("checksum mismatch for session {session_id}: expected {expected}, got {actual}")]
35    ChecksumMismatch {
36        session_id: String,
37        expected: String,
38        actual: String,
39    },
40
41    /// Version incompatibility.
42    #[error("version incompatible: file version {file_version}, supported {supported_version}")]
43    VersionIncompatible {
44        file_version: u32,
45        supported_version: u32,
46    },
47
48    /// Permission denied.
49    #[error("permission denied: {0}")]
50    PermissionDenied(String),
51
52    /// Snapshot restore failed for an Enabled component.
53    #[error("snapshot restore failed: {0}")]
54    Snapshot(#[from] orcs_component::SnapshotError),
55}
56
57impl StorageError {
58    /// Creates a NotFound error.
59    pub fn not_found(id: impl Into<String>) -> Self {
60        Self::NotFound(id.into())
61    }
62
63    /// Creates an InvalidPath error.
64    pub fn invalid_path(path: impl Into<PathBuf>) -> Self {
65        Self::InvalidPath(path.into())
66    }
67
68    /// Creates a DirectoryCreation error.
69    pub fn directory_creation(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
70        Self::DirectoryCreation {
71            path: path.into(),
72            source,
73        }
74    }
75
76    /// Creates a ChecksumMismatch error.
77    pub fn checksum_mismatch(
78        session_id: impl Into<String>,
79        expected: impl Into<String>,
80        actual: impl Into<String>,
81    ) -> Self {
82        Self::ChecksumMismatch {
83            session_id: session_id.into(),
84            expected: expected.into(),
85            actual: actual.into(),
86        }
87    }
88
89    /// Returns `true` if this is a recoverable error.
90    pub fn is_recoverable(&self) -> bool {
91        matches!(self, Self::NotFound(_) | Self::Io(_))
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn not_found_error() {
101        let err = StorageError::not_found("session-123");
102        assert!(matches!(err, StorageError::NotFound(_)));
103        assert!(err.to_string().contains("session-123"));
104    }
105
106    #[test]
107    fn invalid_path_error() {
108        let err = StorageError::invalid_path("/invalid/path");
109        assert!(matches!(err, StorageError::InvalidPath(_)));
110    }
111
112    #[test]
113    fn is_recoverable() {
114        assert!(StorageError::not_found("x").is_recoverable());
115        assert!(!StorageError::VersionIncompatible {
116            file_version: 1,
117            supported_version: 2
118        }
119        .is_recoverable());
120    }
121}