Skip to main content

mini_docs/
error.rs

1use std::fmt;
2
3/// Errors that can occur while building a Markdown → HTML site.
4///
5/// This error type is non-exhaustive and may gain new variants in future releases.
6///
7/// # Variants
8///
9/// - `Frontmatter`: the `---`-delimited frontmatter block is malformed.
10/// - `Markdown`: Markdown rendering failed.
11/// - `Template`: Tera template loading or rendering failed.
12/// - `Io`: an I/O error occurred (file read, write, or directory walk).
13/// - `Escape`: a resolved output path would have written outside `output_dir`.
14#[derive(Debug)]
15#[non_exhaustive]
16pub enum DocError {
17    /// Malformed frontmatter block.
18    Frontmatter(String),
19    /// Markdown render failure.
20    Markdown(String),
21    /// Tera template load/render failure.
22    Template(tera::Error),
23    /// I/O error from the filesystem.
24    Io(std::io::Error),
25    /// Output path resolved outside `output_dir`.
26    Escape(String),
27}
28
29impl fmt::Display for DocError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            DocError::Frontmatter(msg) => write!(f, "invalid frontmatter: {msg}"),
33            DocError::Markdown(msg) => write!(f, "markdown render error: {msg}"),
34            DocError::Template(e) => write!(f, "template error: {e}"),
35            DocError::Io(e) => write!(f, "io error: {e}"),
36            DocError::Escape(path) => write!(f, "output path escaped root: {path}"),
37        }
38    }
39}
40
41impl std::error::Error for DocError {
42    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43        match self {
44            DocError::Template(e) => Some(e),
45            DocError::Io(e) => Some(e),
46            _ => None,
47        }
48    }
49}
50
51impl DocError {
52    /// Returns a user-safe error message, never leaking filesystem or template internals.
53    pub fn user_message(&self) -> String {
54        match self {
55            DocError::Frontmatter(_) => "invalid frontmatter".to_string(),
56            DocError::Markdown(_) => "could not render markdown".to_string(),
57            DocError::Template(_) => "template error".to_string(),
58            DocError::Io(_) => "io error".to_string(),
59            DocError::Escape(_) => "output path escaped root".to_string(),
60        }
61    }
62}
63
64impl From<std::io::Error> for DocError {
65    fn from(e: std::io::Error) -> Self {
66        DocError::Io(e)
67    }
68}