Skip to main content

musefs_core/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum CoreError {
5    #[error(transparent)]
6    Db(#[from] musefs_db::DbError),
7    #[error("failed to open database at {path}")]
8    DbOpen {
9        path: std::path::PathBuf,
10        #[source]
11        source: musefs_db::DbError,
12    },
13    #[error(transparent)]
14    Format(#[from] musefs_format::FormatError),
15    #[error(transparent)]
16    InvalidTemplate(#[from] crate::template::TemplateError),
17    #[error("MP4 {box_kind} box is {size} bytes, exceeds the {cap}-byte metadata cap")]
18    Mp4MetadataTooLarge {
19        box_kind: &'static str,
20        size: u64,
21        cap: u64,
22    },
23    #[error(transparent)]
24    Io(#[from] std::io::Error),
25    #[error("backing file I/O at {path}: {source}")]
26    BackingIo {
27        path: std::path::PathBuf,
28        #[source]
29        source: std::io::Error,
30    },
31    #[error("backing file changed since scan: {0}")]
32    BackingChanged(String),
33    #[error(
34        "track {track_id} references art {art_id}, which has no metadata row (orphaned track_art — DB contract violation)"
35    )]
36    OrphanedArt { track_id: i64, art_id: i64 },
37    #[error(
38        "track {track_id} art {art_id} has out-of-range picture_type {value} (expected 0..=20)"
39    )]
40    InvalidPictureType {
41        track_id: i64,
42        art_id: i64,
43        value: u32,
44    },
45    #[error("track {track_id} art {art_id} is {byte_len} bytes, exceeds the {cap}-byte art cap")]
46    ArtTooLarge {
47        track_id: i64,
48        art_id: i64,
49        byte_len: u64,
50        cap: u64,
51    },
52    #[error("front/header read of {requested} bytes exceeds the {cap}-byte serve cap")]
53    HeaderTooLarge { requested: u64, cap: u64 },
54    #[error("track {0} not found")]
55    TrackNotFound(i64),
56    #[error("no such inode: {0}")]
57    NoEntry(u64),
58    #[error("inode {0} is a directory")]
59    IsDir(u64),
60    #[error("inode {0} is not a directory")]
61    NotADir(u64),
62    #[error("handle table full")]
63    HandleTableFull,
64}
65
66impl CoreError {
67    /// Attach the backing-file path to an I/O error. A moved, permission-denied,
68    /// or failing backing file is the most common passthrough failure; carrying
69    /// the path makes the warn log and any surfaced error name the file rather
70    /// than collapsing to a bare `EIO` (#521).
71    pub(crate) fn backing_io(path: impl AsRef<std::path::Path>, source: std::io::Error) -> Self {
72        CoreError::BackingIo {
73            path: path.as_ref().to_path_buf(),
74            source,
75        }
76    }
77}
78
79pub type Result<T> = std::result::Result<T, CoreError>;