Skip to main content

ironcalc/
error.rs

1use std::io;
2use std::num::{ParseFloatError, ParseIntError};
3use thiserror::Error;
4use zip::result::ZipError;
5
6#[derive(Error, Debug, PartialEq, Eq)]
7pub enum XlsxError {
8    #[error("I/O Error: {0}")]
9    IO(String),
10    #[error("Zip Error: {0}")]
11    Zip(String),
12    #[error("XML Error: {0}")]
13    Xml(String),
14    #[error("{0}")]
15    Workbook(String),
16    #[error("Evaluation Error: {}", .0.join("; "))]
17    Evaluation(Vec<String>),
18    #[error("Comparison Error: {0}")]
19    Comparison(String),
20    #[error("Not Implemented Error: {0}")]
21    NotImplemented(String),
22}
23
24impl From<io::Error> for XlsxError {
25    fn from(error: io::Error) -> Self {
26        XlsxError::IO(error.to_string())
27    }
28}
29
30impl From<ZipError> for XlsxError {
31    fn from(error: ZipError) -> Self {
32        XlsxError::Zip(error.to_string())
33    }
34}
35
36impl From<ParseIntError> for XlsxError {
37    fn from(error: ParseIntError) -> Self {
38        XlsxError::Xml(error.to_string())
39    }
40}
41
42impl From<ParseFloatError> for XlsxError {
43    fn from(error: ParseFloatError) -> Self {
44        XlsxError::Xml(error.to_string())
45    }
46}
47
48impl From<quick_xml::Error> for XlsxError {
49    fn from(error: quick_xml::Error) -> Self {
50        XlsxError::Xml(error.to_string())
51    }
52}
53
54impl From<quick_xml::events::attributes::AttrError> for XlsxError {
55    fn from(error: quick_xml::events::attributes::AttrError) -> Self {
56        XlsxError::Xml(error.to_string())
57    }
58}
59
60impl XlsxError {
61    pub fn user_message(&self) -> String {
62        match &self {
63            XlsxError::IO(_) | XlsxError::Workbook(_) => self.to_string(),
64            XlsxError::Zip(_) | XlsxError::Xml(_) => {
65                "IronCalc can only open workbooks created by Microsoft Excel. \
66                Can you open this file with Excel, save it to a new file, \
67                and then open that new file with IronCalc? If you've already tried this, \
68                then send this workbook to support@ironcalc.com and our engineering team \
69                will work with you to fix the issue."
70                    .to_string()
71            }
72            XlsxError::NotImplemented(error) => format!(
73                "IronCalc cannot open this workbook due to the following unsupported features: \
74                {error}. You can either re-implement these parts of your workbook using features \
75                supported by IronCalc, or you can send this workbook to support@ironcalc.com \
76                and our engineering team will work with you to fix the issue.",
77            ),
78            XlsxError::Evaluation(errors) => format!(
79                "IronCalc could not evaluate this workbook without errors. This may indicate a bug or missing feature \
80                in the IronCalc spreadsheet calculation engine. Please contact support@ironcalc.com, share the entirety \
81                of this error message and the relevant workbook, and we will work with you to resolve the issue. \
82                Detailed error message:\n{}",
83                errors.join("\n")
84            ),
85            XlsxError::Comparison(error) => format!(
86                "IronCalc produces different results when evaluating the workbook \
87                than those already present in the workbook. This may indicate a bug or missing \
88                feature in the IronCalc spreadsheet calculation engine. Please contact \
89                support@ironcalc.com, share the entirety of this error message and the relevant \
90                workbook, and we will work with you to resolve the issue. \
91                Detailed error message:\n{error}"
92            ),
93        }
94    }
95}