scrape_core/
error.rs

1//! Error types for scrape-core.
2
3use thiserror::Error;
4
5/// Result type alias using [`enum@Error`].
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Errors that can occur during HTML parsing and querying.
9#[derive(Debug, Error)]
10pub enum Error {
11    /// Failed to parse HTML document.
12    #[error("failed to parse HTML: {message}")]
13    ParseError {
14        /// Description of what went wrong.
15        message: String,
16    },
17
18    /// Invalid CSS selector syntax.
19    #[error("invalid CSS selector: {selector}")]
20    InvalidSelector {
21        /// The selector string that failed to parse.
22        selector: String,
23    },
24
25    /// Element not found.
26    #[error("element not found: {query}")]
27    NotFound {
28        /// The query that returned no results.
29        query: String,
30    },
31
32    /// Attribute not found on element.
33    #[error("attribute '{name}' not found on element")]
34    AttributeNotFound {
35        /// The attribute name that was not found.
36        name: String,
37    },
38
39    /// I/O error when reading from file or network.
40    #[error("I/O error: {0}")]
41    Io(#[from] std::io::Error),
42}
43
44impl Error {
45    /// Creates a new parse error with the given message.
46    #[must_use]
47    pub fn parse(message: impl Into<String>) -> Self {
48        Self::ParseError { message: message.into() }
49    }
50
51    /// Creates a new invalid selector error.
52    #[must_use]
53    pub fn invalid_selector(selector: impl Into<String>) -> Self {
54        Self::InvalidSelector { selector: selector.into() }
55    }
56
57    /// Creates a new not found error.
58    #[must_use]
59    pub fn not_found(query: impl Into<String>) -> Self {
60        Self::NotFound { query: query.into() }
61    }
62
63    /// Creates a new attribute not found error.
64    #[must_use]
65    pub fn attribute_not_found(name: impl Into<String>) -> Self {
66        Self::AttributeNotFound { name: name.into() }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn test_error_display() {
76        let err = Error::parse("unexpected end of input");
77        assert_eq!(err.to_string(), "failed to parse HTML: unexpected end of input");
78
79        let err = Error::invalid_selector("div[");
80        assert_eq!(err.to_string(), "invalid CSS selector: div[");
81
82        let err = Error::not_found("div.missing");
83        assert_eq!(err.to_string(), "element not found: div.missing");
84
85        let err = Error::attribute_not_found("href");
86        assert_eq!(err.to_string(), "attribute 'href' not found on element");
87    }
88}