Skip to main content

nectar_primitives/file/
error.rs

1//! Error types for file splitting and joining operations.
2
3use crate::ChunkAddress;
4use thiserror::Error;
5
6/// Errors from file splitting and joining operations.
7#[non_exhaustive]
8#[derive(Error, Debug)]
9pub enum FileError {
10    /// Write exceeded the declared span length.
11    #[error("write past span length: wrote {written} bytes, span is {span}")]
12    WritePastSpan {
13        /// Declared span length.
14        span: u64,
15        /// Bytes written so far.
16        written: u64,
17    },
18
19    /// Chunk data exceeds maximum allowed size.
20    #[error("chunk too large: max {max}, got {actual}")]
21    ChunkTooLarge {
22        /// Maximum allowed size.
23        max: usize,
24        /// Actual size.
25        actual: usize,
26    },
27
28    /// Chunk store failed to store a chunk.
29    #[error("store error")]
30    Store(#[source] Box<dyn std::error::Error + Send + Sync>),
31
32    /// Write sink failed. Rendered to a string so the error stays `Send + Sync`
33    /// even when the sink's own error is not (a single-threaded browser
34    /// writable).
35    #[error("sink error: {0}")]
36    Sink(String),
37
38    /// Chunk getter failed to retrieve a chunk.
39    #[error("getter error")]
40    Getter(#[source] Box<dyn std::error::Error + Send + Sync>),
41
42    /// Invalid chunk reference encountered during tree traversal.
43    #[error("invalid reference at level {level}")]
44    InvalidReference {
45        /// Tree level where the invalid reference was found.
46        level: usize,
47    },
48
49    /// Required chunk was not found.
50    #[error("chunk not found: {0}")]
51    ChunkNotFound(ChunkAddress),
52
53    /// Span value doesn't match expected value.
54    #[error("span mismatch: expected {expected}, got {actual}")]
55    SpanMismatch {
56        /// Expected span value.
57        expected: u64,
58        /// Actual span value.
59        actual: u64,
60    },
61
62    /// Underlying chunk error.
63    #[error("chunk error: {0}")]
64    Chunk(#[from] crate::chunk::error::ChunkError),
65
66    /// Encryption error.
67    #[error("encryption error: {0}")]
68    Encryption(#[from] crate::chunk::encryption::EncryptionError),
69
70    /// Invalid entry reference length (expected 32 or 64 bytes).
71    #[error("invalid entry reference length: {len} (expected 32 or 64)")]
72    InvalidEntryRef {
73        /// Actual byte length of the reference.
74        len: usize,
75    },
76
77    /// Expected a content chunk but got a different chunk type.
78    #[error("expected content chunk, got {type_name}")]
79    InvalidChunkType {
80        /// Name of the chunk type that was received.
81        type_name: &'static str,
82    },
83}
84
85impl FileError {
86    /// Create a store error from any error type.
87    pub fn store<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self {
88        Self::Store(Box::new(err))
89    }
90
91    /// Create a getter error from any error type.
92    pub fn getter<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self {
93        Self::Getter(Box::new(err))
94    }
95
96    /// Create a sink error by rendering any sink error to a string. Keeps
97    /// `FileError: Send + Sync` while accepting a `!Send` wasm sink error.
98    pub fn sink<E: std::error::Error>(err: E) -> Self {
99        Self::Sink(err.to_string())
100    }
101}
102
103/// Result type for file operations.
104pub type Result<T> = std::result::Result<T, FileError>;