Skip to main content

codetether_agent/browser/
error.rs

1use thiserror::Error;
2
3#[path = "error_cdp.rs"]
4mod cdp;
5
6#[allow(dead_code)]
7#[derive(Debug, Error)]
8pub enum BrowserError {
9    #[error("browser command is not implemented")]
10    NotImplemented,
11    #[error("navigation timed out")]
12    NavigationTimeout,
13    #[error("element not found: {0}")]
14    ElementNotFound(String),
15    #[error("javascript exception: {message}{stack_suffix}", stack_suffix = stack_suffix(.stack.as_deref()))]
16    JsException {
17        message: String,
18        stack: Option<String>,
19    },
20    #[error("browser session not started")]
21    SessionNotStarted,
22    #[error("tab is closed")]
23    TabClosed,
24    #[error("browser crashed or connection was lost")]
25    BrowserCrashed,
26    #[error("evaluation timed out")]
27    EvaluationTimeout,
28    #[error("evaluation promise rejected: {message}")]
29    EvalRejection { message: String },
30    #[error(
31        "evaluation returned non-serializable value: {description} (type={type_}, subtype={subtype:?})"
32    )]
33    EvalNonSerializable {
34        type_: String,
35        subtype: Option<String>,
36        description: String,
37    },
38    #[error("evaluation wrapper error: {0}")]
39    EvalWrapperError(String),
40    #[error("browser operation failed: {0}")]
41    OperationFailed(String),
42}
43
44impl From<anyhow::Error> for BrowserError {
45    fn from(error: anyhow::Error) -> Self {
46        Self::OperationFailed(error.to_string())
47    }
48}
49
50impl From<serde_json::Error> for BrowserError {
51    fn from(error: serde_json::Error) -> Self {
52        Self::OperationFailed(error.to_string())
53    }
54}
55
56fn stack_suffix(stack: Option<&str>) -> String {
57    stack.map(|value| format!("\n{value}")).unwrap_or_default()
58}