Skip to main content

typst_batch/diagnostic/
error.rs

1//! Compilation error type.
2
3use thiserror::Error;
4use typst::diag::SourceDiagnostic;
5use typst::World;
6
7use super::info::Diagnostics;
8use crate::world::SnapshotError;
9
10/// Error type for Typst compilation failures.
11///
12/// This provides structured access to compilation errors for programmatic handling,
13/// while also implementing `Display` for human-readable output.
14///
15/// # Example
16///
17/// ```ignore
18/// match compile_html(path, root) {
19///     Ok(result) => { /* success */ }
20///     Err(CompileError::Compilation { diagnostics, .. }) => {
21///         // Access individual errors
22///         for diag in diagnostics.errors() {
23///             eprintln!("Error: {}", diag.message);
24///         }
25///     }
26///     Err(CompileError::HtmlExport { message }) => {
27///         eprintln!("HTML export failed: {message}");
28///     }
29///     Err(e) => eprintln!("{e}"),
30/// }
31/// ```
32#[derive(Debug, Error)]
33pub enum CompileError {
34    /// Typst compilation failed with diagnostics.
35    #[error("{diagnostics}")]
36    Compilation {
37        /// The resolved diagnostics.
38        diagnostics: Diagnostics,
39    },
40
41    /// HTML export failed.
42    #[error("HTML export failed: {message}")]
43    HtmlExport {
44        /// Error message from typst_html.
45        message: String,
46    },
47
48    /// File I/O error.
49    #[error("I/O error: {0}")]
50    Io(#[from] std::io::Error),
51
52    /// Snapshot build error.
53    #[error("snapshot error: {0}")]
54    Snapshot(#[from] SnapshotError),
55}
56
57impl CompileError {
58    /// Create a compilation error from raw diagnostics.
59    pub fn compilation<W: World>(world: &W, raw_diagnostics: Vec<SourceDiagnostic>) -> Self {
60        Self::compilation_with_offset(world, raw_diagnostics, 0)
61    }
62
63    /// Create a compilation error with line offset for main file.
64    pub fn compilation_with_offset<W: World>(
65        world: &W,
66        raw_diagnostics: Vec<SourceDiagnostic>,
67        main_line_offset: usize,
68    ) -> Self {
69        let diagnostics = Diagnostics::resolve_with_offset(world, &raw_diagnostics, main_line_offset);
70        Self::Compilation { diagnostics }
71    }
72
73    /// Create an HTML export error.
74    pub fn html_export(message: impl Into<String>) -> Self {
75        Self::HtmlExport {
76            message: message.into(),
77        }
78    }
79
80    /// Check if this error contains any fatal errors (vs just warnings).
81    pub fn has_fatal_errors(&self) -> bool {
82        match self {
83            Self::Compilation { diagnostics } => diagnostics.has_errors(),
84            _ => true,
85        }
86    }
87
88    /// Get the diagnostics if this is a compilation error.
89    pub fn diagnostics(&self) -> Option<&Diagnostics> {
90        match self {
91            Self::Compilation { diagnostics } => Some(diagnostics),
92            _ => None,
93        }
94    }
95}