1use crate::api_error::PdfError;
4
5#[derive(Debug, thiserror::Error)]
7pub enum EngineError {
8 #[error("invalid PDF: {0}")]
10 InvalidPdf(String),
11
12 #[error("page {index} out of range (document has {count} pages)")]
14 PageOutOfRange {
15 index: usize,
17 count: usize,
19 },
20
21 #[error("render error: {0}")]
23 RenderError(String),
24
25 #[error(transparent)]
27 Io(#[from] std::io::Error),
28
29 #[error("PDF is encrypted: {0}")]
31 Encrypted(String),
32
33 #[error("invalid page geometry (w={width:.2}pt, h={height:.2}pt): {reason}")]
35 InvalidPageGeometry {
36 width: f32,
38 height: f32,
40 reason: String,
42 },
43
44 #[error("XFA flatten failed: {0}")]
46 XfaFlattenFailed(String),
47}
48
49impl PdfError for EngineError {
50 fn code(&self) -> &str {
51 match self {
52 EngineError::InvalidPdf(_) => "INVALID_PDF",
53 EngineError::PageOutOfRange { .. } => "PAGE_OUT_OF_RANGE",
54 EngineError::RenderError(_) => "RENDER_ERROR",
55 EngineError::Io(_) => "IO_ERROR",
56 EngineError::Encrypted(_) => "ENCRYPTED",
57 EngineError::InvalidPageGeometry { .. } => "INVALID_PAGE_GEOMETRY",
58 EngineError::XfaFlattenFailed(_) => "XFA_FLATTEN_FAILED",
59 }
60 }
61
62 fn help(&self) -> Option<String> {
63 match self {
64 EngineError::InvalidPdf(_) => {
65 Some("The PDF file is corrupt or invalid. Try using a PDF repair tool or re-save the document.".to_string())
66 }
67 EngineError::PageOutOfRange { index, count } => {
68 Some(format!("Page {} does not exist. This document has {} pages (0-{}).", index, count, count - 1))
69 }
70 EngineError::RenderError(_) => {
71 Some("Rendering failed. Check that the page exists and the document is not corrupted.".to_string())
72 }
73 EngineError::Io(_) => {
74 Some("An I/O error occurred. Check file permissions and disk space.".to_string())
75 }
76 EngineError::Encrypted(_) => {
77 Some("The PDF is encrypted. Provide the correct password to open it.".to_string())
78 }
79 EngineError::InvalidPageGeometry { .. } => {
80 Some("The page has invalid or degenerate dimensions and cannot be rendered.".to_string())
81 }
82 EngineError::XfaFlattenFailed(_) => {
83 Some("XFA flattening produced an invalid PDF. The document may use unsupported XFA features.".to_string())
84 }
85 }
86 }
87}
88
89pub type Result<T> = std::result::Result<T, EngineError>;
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn encrypted_error_code() {
98 let e = EngineError::Encrypted("bad password".into());
99 assert_eq!(e.code(), "ENCRYPTED");
100 }
101
102 #[test]
103 fn invalid_page_geometry_error_code() {
104 let e = EngineError::InvalidPageGeometry {
105 width: 0.5,
106 height: 0.5,
107 reason: "test".into(),
108 };
109 assert_eq!(e.code(), "INVALID_PAGE_GEOMETRY");
110 }
111
112 #[test]
113 fn xfa_flatten_failed_error_code() {
114 let e = EngineError::XfaFlattenFailed("corrupt output".into());
115 assert_eq!(e.code(), "XFA_FLATTEN_FAILED");
116 }
117}