1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum SpiderError {
8 #[error("Connection error: {message}")]
9 Connection {
10 message: String,
11 ws_code: Option<u16>,
12 },
13
14 #[error("Authentication failed: {0}")]
15 Auth(String),
16
17 #[error("Rate limited: {message}")]
18 RateLimit {
19 message: String,
20 retry_after_ms: Option<u64>,
21 },
22
23 #[error("Blocked: {0}")]
24 Blocked(String),
25
26 #[error("Backend unavailable: {0}")]
27 BackendUnavailable(String),
28
29 #[error("Navigation failed: {0}")]
30 Navigation(String),
31
32 #[error("Timeout: {0}")]
33 Timeout(String),
34
35 #[error("Protocol error: {0}")]
36 Protocol(String),
37
38 #[error("LLM error: {0}")]
39 Llm(String),
40
41 #[error("{0}")]
42 Other(String),
43}
44
45impl SpiderError {
46 pub fn is_retryable(&self) -> bool {
47 !matches!(self, SpiderError::Auth(_) | SpiderError::Protocol(_))
48 }
49
50 pub fn connection(msg: impl Into<String>) -> Self {
51 SpiderError::Connection {
52 message: msg.into(),
53 ws_code: None,
54 }
55 }
56
57 pub fn connection_with_code(msg: impl Into<String>, code: u16) -> Self {
58 SpiderError::Connection {
59 message: msg.into(),
60 ws_code: Some(code),
61 }
62 }
63
64 pub fn rate_limit(msg: impl Into<String>) -> Self {
65 SpiderError::RateLimit {
66 message: msg.into(),
67 retry_after_ms: None,
68 }
69 }
70
71 pub fn rate_limit_with_retry(msg: impl Into<String>, retry_ms: u64) -> Self {
72 SpiderError::RateLimit {
73 message: msg.into(),
74 retry_after_ms: Some(retry_ms),
75 }
76 }
77}
78
79pub type Result<T> = std::result::Result<T, SpiderError>;