cas_kit/error.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Error types for the content-addressed store.
3
4use std::io;
5
6use thiserror::Error;
7
8use crate::pack::PackError;
9
10/// Errors that can occur during CAS operations.
11#[derive(Error, Debug)]
12pub enum CasError {
13 /// The requested blob does not exist in the store (loose or packed).
14 #[error("blob not found: {0}")]
15 BlobNotFound(String),
16
17 /// The stored bytes did not hash to the requested address.
18 #[error("hash mismatch: expected {expected}, got {actual}")]
19 HashMismatch {
20 /// The hash the blob was addressed by.
21 expected: String,
22 /// The hash of what was actually read back.
23 actual: String,
24 },
25
26 /// A mutex protecting interior cache state was poisoned.
27 #[error("lock poisoned: {0}")]
28 LockPoisoned(String),
29
30 /// An underlying filesystem operation failed.
31 #[error("I/O error: {0}")]
32 Io(#[from] io::Error),
33
34 /// Zstd compression failed (requires the `zstd` feature).
35 #[error("compression error: {0}")]
36 CompressionError(String),
37
38 /// Zstd decompression failed (requires the `zstd` feature).
39 #[error("decompression error: {0}")]
40 DecompressionError(String),
41
42 /// Decompressed data exceeded the configured safety limit
43 /// (zip-bomb protection).
44 #[error("decompressed data too large: {max} bytes max")]
45 DecompressionTooLarge {
46 /// The maximum accepted decompressed size in bytes.
47 max: usize,
48 },
49
50 /// [`crate::store::BlobStore::put_blob_new`] was called for an existing blob.
51 #[error("blob already exists: {0}")]
52 AlreadyExists(String),
53
54 /// A derived path was not usable (e.g. malformed hex on disk).
55 #[error("invalid path: {0}")]
56 InvalidPath(String),
57
58 /// A packfile operation failed.
59 #[error("pack error: {0}")]
60 Pack(#[from] PackError),
61
62 /// A garbage-collection sweep was asked to trash or delete a path
63 /// outside the store root (internal invariant violation).
64 #[error("gc path outside store root: {0}")]
65 GcPathEscape(String),
66
67 /// A `spawn_blocking` task joined by an async GC wrapper panicked or
68 /// the tokio runtime was already shut down (requires the `tokio`
69 /// feature).
70 #[error("background gc task failed: {0}")]
71 TaskJoin(String),
72}