diff --git a/crates/dav/src/error.rs b/crates/dav/src/error.rs index ec0fa1d..61d7b21 100644 --- a/crates/dav/src/error.rs +++ b/crates/dav/src/error.rs @@ -1,4 +1,5 @@ use actix_web::{http::StatusCode, HttpResponse}; +use rustical_xml::XmlError; use thiserror::Error; use tracing::error; @@ -33,7 +34,15 @@ impl actix_web::error::ResponseError for Error { Self::NotFound => StatusCode::NOT_FOUND, Self::BadRequest(_) => StatusCode::BAD_REQUEST, Self::Unauthorized => StatusCode::UNAUTHORIZED, - Self::XmlError(_) => StatusCode::BAD_REQUEST, + Self::XmlError(error) => match &error { + XmlError::InvalidTag(..) + | XmlError::MissingField(_) + | XmlError::UnsupportedEvent(_) + | XmlError::InvalidVariant(_) + | XmlError::InvalidFieldName(_, _) + | XmlError::InvalidValue(_) => StatusCode::UNPROCESSABLE_ENTITY, + _ => StatusCode::BAD_REQUEST, + }, Error::PropReadOnly => StatusCode::CONFLICT, Self::IOError(_) => StatusCode::INTERNAL_SERVER_ERROR, } diff --git a/crates/dav/src/xml/sync_collection.rs b/crates/dav/src/xml/sync_collection.rs index e816f69..deb53b4 100644 --- a/crates/dav/src/xml/sync_collection.rs +++ b/crates/dav/src/xml/sync_collection.rs @@ -14,8 +14,8 @@ impl ValueDeserialize for SyncLevel { "1" => Self::One, "Infinity" => Self::Infinity, _ => { - return Err(rustical_xml::XmlError::Other( - "Invalid sync-level".to_owned(), + return Err(rustical_xml::XmlError::InvalidValue( + rustical_xml::ParseValueError::Other("Invalid sync-level".to_owned()), )) } }) diff --git a/crates/store/src/calendar/object.rs b/crates/store/src/calendar/object.rs index 7ea68cd..9e23f85 100644 --- a/crates/store/src/calendar/object.rs +++ b/crates/store/src/calendar/object.rs @@ -30,10 +30,12 @@ impl rustical_xml::ValueDeserialize for CalendarObjectType { "VEVENT" => Ok(Self::Event), "VTODO" => Ok(Self::Todo), "VJOURNAL" => Ok(Self::Journal), - _ => Err(rustical_xml::XmlError::Other(format!( - "Invalid value '{}', must be VEVENT, VTODO, or VJOURNAL", - val - ))), + _ => Err(rustical_xml::XmlError::InvalidValue( + rustical_xml::ParseValueError::Other(format!( + "Invalid value '{}', must be VEVENT, VTODO, or VJOURNAL", + val + )), + )), } } } diff --git a/crates/store/src/calendar/timestamp.rs b/crates/store/src/calendar/timestamp.rs index 0d2e44c..4f02e80 100644 --- a/crates/store/src/calendar/timestamp.rs +++ b/crates/store/src/calendar/timestamp.rs @@ -30,7 +30,9 @@ impl ValueDeserialize for UtcDateTime { Ok(Self( NaiveDateTime::parse_from_str(&input, UTC_DATE_TIME) .map_err(|_| { - rustical_xml::XmlError::Other("Could not parse as UTC timestamp".to_owned()) + rustical_xml::XmlError::InvalidValue(rustical_xml::ParseValueError::Other( + "Could not parse as UTC timestamp".to_owned(), + )) })? .and_utc(), )) diff --git a/crates/xml/derive/src/xml_enum.rs b/crates/xml/derive/src/xml_enum.rs index 3d2e218..4faa235 100644 --- a/crates/xml/derive/src/xml_enum.rs +++ b/crates/xml/derive/src/xml_enum.rs @@ -165,7 +165,6 @@ impl Enum { Event::Start(start) | Event::Empty(start) => { return ::deserialize(&mut reader, &start, empty); } - Event::Eof => return Err(::rustical_xml::XmlError::Eof), Event::Text(bytes_text) => { return Err(::rustical_xml::XmlError::UnsupportedEvent("Text")); @@ -173,19 +172,14 @@ impl Enum { Event::CData(cdata) => { return Err(::rustical_xml::XmlError::UnsupportedEvent("CDATA")); } + Event::Decl(_) => { /* ignore this */ } Event::Comment(_) => { /* ignore */ } - Event::Decl(_) => { - /* ignore */ - // return Err(::rustical_xml::XmlError::UnsupportedEvent("Declaration")); - } + Event::DocType(_) => { /* ignore */ } Event::PI(_) => { return Err(::rustical_xml::XmlError::UnsupportedEvent("Processing instruction")); } - Event::DocType(doctype) => { - return Err(::rustical_xml::XmlError::UnsupportedEvent("Doctype in the middle of the document")); - } Event::End(end) => { - return Err(::rustical_xml::XmlError::UnsupportedEvent("Premature end")); + unreachable!("Premature end of xml document, should be handled by quick_xml"); } }; } diff --git a/crates/xml/derive/src/xml_struct.rs b/crates/xml/derive/src/xml_struct.rs index 6f3e964..e4a9eab 100644 --- a/crates/xml/derive/src/xml_struct.rs +++ b/crates/xml/derive/src/xml_struct.rs @@ -179,22 +179,15 @@ impl NamedStruct { let text = String::from_utf8(cdata.to_vec())?; #(#text_field_branches)* } + Event::Decl(_) => { /* ignore this */ } Event::Comment(_) => { /* ignore */ } - Event::Decl(_) => { - // Error: not supported - return Err(XmlError::UnsupportedEvent("Declaration")); - } + Event::DocType(_) => { /* ignore */ } Event::PI(_) => { // Error: not supported return Err(XmlError::UnsupportedEvent("Processing instruction")); } - Event::DocType(doctype) => { - // Error: start of new document - return Err(XmlError::UnsupportedEvent("Doctype in the middle of the document")); - } Event::End(end) => { - // This should actually be unreachable - return Err(XmlError::Other("Unexpected closing tag for wrong element".to_owned())); + unreachable!("Unexpected closing tag for wrong element, should be handled by quick_xml"); } } } diff --git a/crates/xml/src/de.rs b/crates/xml/src/de.rs index 2c52a1b..6cce7f0 100644 --- a/crates/xml/src/de.rs +++ b/crates/xml/src/de.rs @@ -67,6 +67,7 @@ impl XmlDocument for T { return Self::deserialize(&mut reader, &start, empty); } + Event::Eof => return Err(XmlError::Eof), _ => return Err(XmlError::UnsupportedEvent("unknown, todo")), }; } diff --git a/crates/xml/src/error.rs b/crates/xml/src/error.rs index 76c7008..c147975 100644 --- a/crates/xml/src/error.rs +++ b/crates/xml/src/error.rs @@ -4,22 +4,23 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum XmlError { + // Syntactix errors #[error(transparent)] QuickXmlError(#[from] quick_xml::Error), #[error(transparent)] QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError), #[error(transparent)] FromUtf8Error(#[from] FromUtf8Error), - #[error("Invalid tag [{0}]{1}. Expected [{2}]{3}")] - InvalidTag(String, String, String, String), - #[error("Missing field {0}")] - MissingField(&'static str), #[error("End of file, expected closing tags")] Eof, #[error("Unsupported xml event: {0}")] UnsupportedEvent(&'static str), - #[error("{0}")] - Other(String), + + // Semantic errors + #[error("Invalid tag [{0}]{1}. Expected [{2}]{3}")] + InvalidTag(String, String, String, String), + #[error("Missing field {0}")] + MissingField(&'static str), #[error("Invalid variant: {0}")] InvalidVariant(String), #[error("Invalid field name in {0}: {1}")] diff --git a/crates/xml/src/value.rs b/crates/xml/src/value.rs index ac5dab2..611bae3 100644 --- a/crates/xml/src/value.rs +++ b/crates/xml/src/value.rs @@ -22,6 +22,8 @@ pub enum ParseValueError { ParseIntError(#[from] ParseIntError), #[error(transparent)] ParseFloatError(#[from] ParseFloatError), + #[error("{0}")] + Other(String), } macro_rules! impl_value_parse {