codetether_browser/browser/
error.rs1use thiserror::Error;
2
3#[allow(dead_code)]
4#[derive(Debug, Error)]
5pub enum BrowserError {
6 #[error("browser command is not implemented: {0}")]
7 NotImplemented(String),
8 #[error("navigation timed out")]
9 NavigationTimeout,
10 #[error("element not found: {0}")]
11 ElementNotFound(String),
12 #[error("element is not fillable: tag={tag}, input_type={input_type:?}")]
13 ElementNotFillable {
14 tag: String,
15 input_type: Option<String>,
16 },
17 #[error("element is not a file input: tag={tag}, input_type={input_type:?}")]
18 ElementNotFileInput {
19 tag: String,
20 input_type: Option<String>,
21 },
22 #[error("file does not exist: {0}")]
23 FileNotFound(String),
24 #[error("file input does not accept multiple files: {0}")]
25 MultipleFilesNotAllowed(String),
26 #[error("waiting for selector timed out: {selector} after {timeout_ms}ms")]
27 WaitTimeout { selector: String, timeout_ms: u64 },
28 #[error("tab not found: {0}")]
29 TabNotFound(usize),
30 #[error("javascript exception: {message}{stack_suffix}", stack_suffix = stack_suffix(.stack.as_deref()))]
31 JsException {
32 message: String,
33 stack: Option<String>,
34 },
35 #[error("browser session not started")]
36 SessionNotStarted,
37 #[error("tab is closed")]
38 TabClosed,
39 #[error("browser crashed or connection was lost")]
40 BrowserCrashed,
41 #[error("evaluation timed out")]
42 EvaluationTimeout,
43 #[error("evaluation promise rejected: {message}")]
44 EvalRejection { message: String },
45 #[error(
46 "evaluation returned non-serializable value: {description} (type={type_}, subtype={subtype:?})"
47 )]
48 EvalNonSerializable {
49 type_: String,
50 subtype: Option<String>,
51 description: String,
52 },
53 #[error("evaluation wrapper error: {0}")]
54 EvalWrapperError(String),
55 #[error("browser operation failed: {0}")]
56 OperationFailed(String),
57}
58
59impl From<anyhow::Error> for BrowserError {
60 fn from(error: anyhow::Error) -> Self {
61 Self::OperationFailed(error.to_string())
62 }
63}
64
65impl From<serde_json::Error> for BrowserError {
66 fn from(error: serde_json::Error) -> Self {
67 Self::OperationFailed(error.to_string())
68 }
69}
70
71fn stack_suffix(stack: Option<&str>) -> String {
72 stack.map(|value| format!("\n{value}")).unwrap_or_default()
73}