Skip to main content

cuenv_cache/
error.rs

1//! Error types for the cache crate
2
3// Rust 1.92 compiler bug: false positives for thiserror/miette derive macro fields
4// https://github.com/rust-lang/rust/issues/147648
5#![allow(unused_assignments)]
6
7use miette::Diagnostic;
8use std::path::Path;
9use thiserror::Error;
10
11/// Error type for cache operations
12#[derive(Error, Debug, Diagnostic)]
13pub enum Error {
14    /// I/O error during cache operations
15    #[error("I/O {operation} failed{}", path.as_ref().map_or(String::new(), |p| format!(": {}", p.display())))]
16    #[diagnostic(
17        code(cuenv::cache::io),
18        help("Check file permissions and ensure the path exists")
19    )]
20    Io {
21        /// The underlying I/O error
22        #[source]
23        source: std::io::Error,
24        /// Path that caused the error, if available
25        path: Option<Box<Path>>,
26        /// Operation that failed (e.g., "read", "write", "create")
27        operation: String,
28    },
29
30    /// Configuration or validation error
31    #[error("Cache configuration error: {message}")]
32    #[diagnostic(code(cuenv::cache::config))]
33    Configuration {
34        /// Error message describing the configuration issue
35        message: String,
36    },
37
38    /// Cache key not found
39    #[error("Cache key not found: {key}")]
40    #[diagnostic(
41        code(cuenv::cache::not_found),
42        help("The cache entry may have been evicted or never existed")
43    )]
44    NotFound {
45        /// The cache key that was not found
46        key: String,
47    },
48
49    /// Serialization error
50    #[error("Serialization error: {message}")]
51    #[diagnostic(code(cuenv::cache::serialization))]
52    Serialization {
53        /// Error message describing the serialization issue
54        message: String,
55    },
56}
57
58impl Error {
59    /// Create a configuration error
60    #[must_use]
61    pub fn configuration(msg: impl Into<String>) -> Self {
62        Self::Configuration {
63            message: msg.into(),
64        }
65    }
66
67    /// Create an I/O error with path context
68    #[must_use]
69    pub fn io(
70        source: std::io::Error,
71        path: impl AsRef<Path>,
72        operation: impl Into<String>,
73    ) -> Self {
74        Self::Io {
75            source,
76            path: Some(path.as_ref().into()),
77            operation: operation.into(),
78        }
79    }
80
81    /// Create an I/O error without path context
82    #[must_use]
83    pub fn io_no_path(source: std::io::Error, operation: impl Into<String>) -> Self {
84        Self::Io {
85            source,
86            path: None,
87            operation: operation.into(),
88        }
89    }
90
91    /// Create a not found error
92    #[must_use]
93    pub fn not_found(key: impl Into<String>) -> Self {
94        Self::NotFound { key: key.into() }
95    }
96
97    /// Create a serialization error
98    #[must_use]
99    pub fn serialization(msg: impl Into<String>) -> Self {
100        Self::Serialization {
101            message: msg.into(),
102        }
103    }
104}
105
106/// Result type for cache operations
107pub type Result<T> = std::result::Result<T, Error>;