orbit_md/error.rs
1//! Domain-specific error types for Orbit.
2//!
3//! All recoverable per-file failures are represented as [`PageError`] so the
4//! parallel pipeline can skip bad inputs without aborting the entire build.
5
6use std::path::PathBuf;
7
8use thiserror::Error;
9
10/// Errors that can occur while building the site.
11#[derive(Debug, Error)]
12pub enum OrbitError {
13 /// Failed to read or write a file on disk.
14 #[error("I/O error at {path}: {source}")]
15 Io {
16 /// Path involved in the failed operation.
17 path: PathBuf,
18 /// Underlying OS error.
19 #[source]
20 source: std::io::Error,
21 },
22
23 /// Site configuration could not be loaded or validated.
24 #[error("configuration error: {0}")]
25 Config(String),
26
27 /// A single page failed to compile; other pages may still succeed.
28 #[error("page error at {path}: {message}")]
29 Page {
30 /// Source file associated with the failure.
31 path: PathBuf,
32 /// Human-readable failure reason.
33 message: String,
34 },
35
36 /// Template engine failure.
37 #[error("template error: {0}")]
38 Template(String),
39
40 /// Front matter could not be deserialized.
41 #[error("front matter parse error at {path}: {source}")]
42 FrontMatter {
43 /// Source file whose front matter failed to parse.
44 path: PathBuf,
45 /// Underlying serde error.
46 #[source]
47 source: serde_yaml::Error,
48 },
49}
50
51/// Per-page failure surfaced during parallel compilation.
52#[derive(Debug, Error)]
53#[error("{message}")]
54pub struct PageError {
55 /// Source path for diagnostics.
56 pub path: PathBuf,
57 /// Failure description.
58 pub message: String,
59}
60
61impl PageError {
62 /// Creates a new page-scoped error.
63 pub fn new(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
64 Self {
65 path: path.into(),
66 message: message.into(),
67 }
68 }
69}
70
71impl From<PageError> for OrbitError {
72 fn from(value: PageError) -> Self {
73 Self::Page {
74 path: value.path,
75 message: value.message,
76 }
77 }
78}