Skip to main content

dodot_lib/
error.rs

1use std::path::PathBuf;
2use thiserror::Error;
3
4/// The single error type for all dodot operations.
5///
6/// Each variant carries enough context to produce a useful error message
7/// without needing to inspect the source chain.
8#[derive(Error, Debug)]
9#[non_exhaustive]
10pub enum DodotError {
11    #[error("filesystem error at {path}: {source}")]
12    Fs {
13        path: PathBuf,
14        source: std::io::Error,
15    },
16
17    #[error("symlink conflict: {path} already exists and is not managed by dodot")]
18    SymlinkConflict { path: PathBuf },
19
20    #[error("protected path: {path} cannot be symlinked")]
21    ProtectedPath { path: PathBuf },
22
23    #[error("pack not found: {name}")]
24    PackNotFound { name: String },
25
26    #[error("pack is invalid: {name}: {reason}")]
27    PackInvalid { name: String, reason: String },
28
29    #[error("handler not found: {name}")]
30    HandlerNotFound { name: String },
31
32    #[error("config error: {0}")]
33    Config(String),
34
35    #[error("command failed: {command} (exit code {exit_code})\n{stderr}")]
36    CommandFailed {
37        command: String,
38        exit_code: i32,
39        stderr: String,
40    },
41
42    #[error("invalid pattern {pattern}: {reason}")]
43    InvalidPattern { pattern: String, reason: String },
44
45    #[error("{0}")]
46    Other(String),
47}
48
49/// Convenience alias used throughout the crate.
50pub type Result<T> = std::result::Result<T, DodotError>;
51
52/// Helper to wrap an `io::Error` with the path that caused it.
53pub(crate) fn fs_err(path: impl Into<PathBuf>, source: std::io::Error) -> DodotError {
54    DodotError::Fs {
55        path: path.into(),
56        source,
57    }
58}