Skip to main content

pdf_xfa/
error.rs

1//! Error types for the XFA engine.
2use thiserror::Error;
3/// XfaError.
4
5#[derive(Debug, Error)]
6pub enum XfaError {
7    /// LoadFailed.
8    // ---- Existing variants (preserved for backwards compatibility) ----
9    #[error("failed to load PDF: {0}")]
10    LoadFailed(String),
11    /// PacketNotFound.
12    #[error("XFA packet not found: {0}")]
13    PacketNotFound(String),
14    /// Encrypted.
15    #[error("encrypted PDF: {0}")]
16    Encrypted(String),
17    /// XmlParse.
18    #[error("XML parse error: {0}")]
19    XmlParse(String),
20    /// FontError.
21    #[error("font error: {0}")]
22    FontError(String),
23    /// LayoutError.
24    #[error("layout error: {0}")]
25    LayoutError(String),
26    /// LayoutFailed.
27    #[error("layout failed: {0}")]
28    LayoutFailed(String),
29    /// ParseFailed.
30    #[error("XML parse failed: {0}")]
31    ParseFailed(String),
32    /// FormCalcError.
33    #[error("FormCalc error: {0}")]
34    FormCalcError(String),
35    /// Io.
36    #[error("IO error: {0}")]
37    Io(#[from] std::io::Error),
38
39    // ---- New structured variants (XFA-F9-01 #1120) ----
40    /// XFA packet extraction failed (e.g. missing /AcroForm, corrupt stream).
41    #[error("XFA extraction failed: {0}")]
42    ExtractionFailed(String),
43
44    /// Template XML could not be parsed.
45    #[error("Template parse error: {0}")]
46    TemplateParse(String),
47
48    /// Data binding from datasets to template failed.
49    #[error("Data binding failed: {0}")]
50    BindingFailed(String),
51    /// LayoutFailedAt.
52    /// LayoutFailedAt.
53
54    /// Layout failed at a specific pipeline stage.
55    ///
56    /// Use this variant when you can identify which stage (e.g. "paginate",
57    /// "split", "occur") caused the failure so callers can give better
58    /// diagnostics.
59    #[error("Layout failed at {stage}: {reason}")]
60    LayoutFailedAt {
61        /// Pipeline stage where layout failed.
62        stage: String,
63        /// Reason for the failure.
64        reason: String,
65    },
66
67    /// PDF content stream generation failed.
68    #[error("Render failed: {0}")]
69    RenderFailed(String),
70
71    /// Final PDF serialisation / flatten step failed.
72    #[error("Flatten failed: {0}")]
73    FlattenFailed(String),
74
75    /// Feature is intentionally unsupported by the non-interactive XFA engine.
76    #[error("unsupported feature: {0}")]
77    UnsupportedFeature(String),
78}
79/// Result.
80pub type Result<T> = std::result::Result<T, XfaError>;
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn error_message_extraction_failed() {
88        let e = XfaError::ExtractionFailed("no /AcroForm key".to_string());
89        assert_eq!(format!("{e}"), "XFA extraction failed: no /AcroForm key");
90    }
91
92    #[test]
93    fn error_message_layout_failed_at() {
94        let e = XfaError::LayoutFailedAt {
95            stage: "paginate".to_string(),
96            reason: "zero-height page area".to_string(),
97        };
98        assert_eq!(
99            format!("{e}"),
100            "Layout failed at paginate: zero-height page area"
101        );
102    }
103}