millipede_browser/
error.rs1use millipede_core::errors::CrawlError;
4
5#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum BrowserError {
9 #[error("no usable browser binary found: {hint}")]
11 BrowserNotFound {
12 hint: String,
14 },
15 #[error("browser launch failed: {0}")]
17 Launch(#[source] anyhow::Error),
18 #[error("page creation failed: {0}")]
20 PageCreate(#[source] anyhow::Error),
21 #[error("navigation to {url} failed: {source}")]
23 Navigation {
24 url: url::Url,
26 #[source]
28 source: anyhow::Error,
29 },
30 #[error("navigation to {url} timed out after {timeout:?}")]
32 NavigationTimeout {
33 url: url::Url,
35 timeout: std::time::Duration,
37 },
38 #[error("waiting for {what} timed out after {timeout:?}")]
40 WaitTimeout {
41 what: String,
43 timeout: std::time::Duration,
45 },
46 #[error("script evaluation failed: {0}")]
48 Evaluation(#[source] anyhow::Error),
49 #[error("cookie conversion failed: {0}")]
51 CookieConversion(#[source] anyhow::Error),
52 #[error("page is already closed")]
54 PageClosed,
55 #[error("browser pool is shut down")]
57 Shutdown,
58 #[error("CDP protocol error: {0}")]
60 Protocol(#[source] anyhow::Error),
61}
62
63impl BrowserError {
64 #[allow(unreachable_patterns)]
66 pub fn classify(self) -> CrawlError {
67 match self {
68 Self::Navigation { .. }
69 | Self::NavigationTimeout { .. }
70 | Self::WaitTimeout { .. }
71 | Self::PageCreate(_)
72 | Self::PageClosed
73 | Self::Protocol(_) => CrawlError::retry(self),
74 Self::BrowserNotFound { .. } | Self::Launch(_) => CrawlError::critical(self),
75 Self::Shutdown | Self::Evaluation(_) | Self::CookieConversion(_) => {
76 CrawlError::non_retryable(self)
77 }
78 _ => CrawlError::non_retryable(self),
79 }
80 }
81}
82
83impl From<BrowserError> for CrawlError {
84 fn from(error: BrowserError) -> Self {
85 error.classify()
86 }
87}