vlr_scraper/
error.rs

1use std::num::ParseIntError;
2
3use scraper::error::SelectorErrorKind;
4
5/// All errors that can occur during VLR scraping operations.
6#[derive(thiserror::Error, Debug)]
7pub enum VlrError {
8    /// HTTP request failed (network, DNS, TLS, timeout, etc.).
9    #[error("http request failed for {url}: {source}")]
10    Http { url: String, source: reqwest::Error },
11
12    /// Server returned a non-success HTTP status code.
13    #[error("unexpected status {status} for {url}")]
14    UnexpectedStatus {
15        url: String,
16        status: reqwest::StatusCode,
17    },
18
19    /// Failed to read the response body as text.
20    #[error("failed to read response body from {url}: {source}")]
21    ResponseBody { url: String, source: reqwest::Error },
22
23    /// A CSS selector string could not be parsed.
24    #[error("invalid CSS selector: {0}")]
25    Selector(String),
26
27    /// Failed to parse an integer from scraped text.
28    #[error("failed to parse integer: {0}")]
29    IntParse(#[from] ParseIntError),
30
31    /// Failed to parse a date/time from scraped text.
32    #[error("failed to parse date: {0}")]
33    DateParse(#[from] chrono::ParseError),
34
35    /// An expected HTML element was not found on the page.
36    #[error("expected element not found: {context}")]
37    ElementNotFound { context: &'static str },
38}
39
40impl<'a> From<SelectorErrorKind<'a>> for VlrError {
41    fn from(err: SelectorErrorKind<'a>) -> Self {
42        VlrError::Selector(err.to_string())
43    }
44}
45
46pub type Result<T> = std::result::Result<T, VlrError>;