mdbook_validator/
error.rs

1//! Structured error types for mdbook-validator.
2//!
3//! Each variant has an error code (E001-E010) for grep-ability
4//! and structured fields for programmatic access.
5
6use thiserror::Error;
7
8/// Errors that can occur during mdbook-validator operations.
9///
10/// Error codes are stable and should not be renumbered.
11/// Add new codes at E011+ if needed in the future.
12#[derive(Debug, Error)]
13pub enum ValidatorError {
14    /// Configuration error (E001)
15    #[error("[E001] Configuration error: {message}")]
16    Config { message: String },
17
18    /// Container startup failed (E002)
19    #[error("[E002] Container startup failed: {message}")]
20    ContainerStartup { message: String },
21
22    /// Container exec failed (E003)
23    #[error("[E003] Container exec failed: {message}")]
24    ContainerExec { message: String },
25
26    /// Setup script failed (E004)
27    #[error("[E004] Setup script failed (exit {exit_code}): {message}")]
28    SetupFailed { exit_code: i32, message: String },
29
30    /// Query execution failed (E005)
31    #[error("[E005] Query execution failed (exit {exit_code}): {message}")]
32    QueryFailed { exit_code: i32, message: String },
33
34    /// Validation failed (E006)
35    #[error("[E006] Validation failed (exit {exit_code}): {message}")]
36    ValidationFailed { exit_code: i32, message: String },
37
38    /// Unknown validator (E007)
39    #[error("[E007] Unknown validator '{name}'")]
40    UnknownValidator { name: String },
41
42    /// Invalid validator config (E008)
43    #[error("[E008] Invalid validator config for '{name}': {reason}")]
44    InvalidConfig { name: String, reason: String },
45
46    /// Fixtures directory error (E009)
47    #[error("[E009] Fixtures directory error: {message}")]
48    FixturesError { message: String },
49
50    /// Script not found (E010)
51    #[error("[E010] Script not found: {path}")]
52    ScriptNotFound { path: String },
53
54    /// Mutually exclusive attributes (E011)
55    #[error("[E011] 'hidden' and 'skip' are mutually exclusive")]
56    MutuallyExclusiveAttributes,
57}
58
59impl ValidatorError {
60    /// Returns the error code (E001-E011) for this error variant.
61    ///
62    /// Error codes are stable and can be used for programmatic matching.
63    #[must_use]
64    pub fn code(&self) -> &'static str {
65        match self {
66            Self::Config { .. } => "E001",
67            Self::ContainerStartup { .. } => "E002",
68            Self::ContainerExec { .. } => "E003",
69            Self::SetupFailed { .. } => "E004",
70            Self::QueryFailed { .. } => "E005",
71            Self::ValidationFailed { .. } => "E006",
72            Self::UnknownValidator { .. } => "E007",
73            Self::InvalidConfig { .. } => "E008",
74            Self::FixturesError { .. } => "E009",
75            Self::ScriptNotFound { .. } => "E010",
76            Self::MutuallyExclusiveAttributes => "E011",
77        }
78    }
79}