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}