1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Error types for playwright-core
use thiserror::Error;
/// Result type alias for playwright-core operations
pub type Result<T> = std::result::Result<T, Error>;
/// Errors that can occur when using playwright-core
#[derive(Debug, Error)]
pub enum Error {
/// Playwright server binary was not found
///
/// The Playwright Node.js driver could not be located.
/// To resolve this, install Playwright using: `npm install playwright`
/// Or ensure the PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD environment variable is not set.
#[error("Playwright server not found. Install with: npm install playwright")]
ServerNotFound,
/// Failed to launch the Playwright server process
///
/// The Playwright server process could not be started.
/// Common causes: Node.js not installed, insufficient permissions, or port already in use.
/// Details: {0}
#[error("Failed to launch Playwright server: {0}. Check that Node.js is installed.")]
LaunchFailed(String),
/// Server error (runtime issue with Playwright server)
#[error("Server error: {0}")]
ServerError(String),
/// Browser is not installed
///
/// The specified browser has not been installed using Playwright's installation command.
/// To resolve this, install browsers using the versioned install command to ensure compatibility.
#[error(
"Browser '{browser_name}' is not installed.\n\n\
{message}\n\n\
To install {browser_name}, run:\n \
npx playwright@{playwright_version} install {browser_name}\n\n\
Or install all browsers:\n \
npx playwright@{playwright_version} install\n\n\
See: https://playwright.dev/docs/browsers"
)]
BrowserNotInstalled {
browser_name: String,
message: String,
playwright_version: String,
},
/// Failed to establish connection with the server
#[error("Failed to connect to Playwright server: {0}")]
ConnectionFailed(String),
/// Transport-level error (stdio communication)
#[error("Transport error: {0}")]
TransportError(String),
/// Protocol-level error (JSON-RPC)
#[error("Protocol error: {0}")]
ProtocolError(String),
/// I/O error
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// JSON serialization/deserialization error
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
/// Timeout waiting for operation
///
/// Contains context about what operation timed out and the timeout duration.
/// Common causes include slow network, server not responding, or element not becoming actionable.
/// Consider increasing the timeout or checking if the target is accessible.
#[error("Timeout: {0}")]
Timeout(String),
/// Navigation timeout
///
/// Occurs when page navigation exceeds the specified timeout.
/// Includes the URL being navigated to and timeout duration.
#[error("Navigation timeout after {duration_ms}ms navigating to '{url}'")]
NavigationTimeout { url: String, duration_ms: u64 },
/// Target was closed (browser, context, or page)
///
/// Occurs when attempting to perform an operation on a closed target.
/// The target must be recreated before it can be used again.
#[error("Target closed: Cannot perform operation on closed {target_type}. {context}")]
TargetClosed {
target_type: String,
context: String,
},
/// Unknown protocol object type
#[error("Unknown protocol object type: {0}")]
UnknownObjectType(String),
/// Channel closed unexpectedly
#[error("Channel closed unexpectedly")]
ChannelClosed,
/// Invalid argument provided to method
#[error("Invalid argument: {0}")]
InvalidArgument(String),
/// Element not found by selector
///
/// Includes the selector that was used to locate the element.
/// This error typically occurs when waiting for an element times out.
#[error("Element not found: selector '{0}'")]
ElementNotFound(String),
/// Assertion timeout (expect API)
#[error("Assertion timeout: {0}")]
AssertionTimeout(String),
/// Assertion failed (expect API, server returned mismatch without timeout)
#[error("Assertion failed: {0}")]
AssertionFailed(String),
/// Object not found in registry (may have been closed/disposed)
#[error("Object not found (may have been closed): {0}")]
ObjectNotFound(String),
/// Type mismatch when downcasting a protocol object
///
/// Occurs when a protocol object's concrete type does not match the expected type.
/// This typically indicates a Playwright protocol version mismatch or a bug in the
/// object factory.
#[error("Type mismatch for object '{guid}': expected {expected}, got {actual}")]
TypeMismatch {
guid: String,
expected: String,
actual: String,
},
/// Invalid path provided
#[error("Invalid path: {0}")]
InvalidPath(String),
/// Error with additional context
#[error("{0}: {1}")]
Context(String, #[source] Box<Error>),
}
impl Error {
/// Adds context to the error
pub fn context(self, msg: impl Into<String>) -> Self {
Error::Context(msg.into(), Box::new(self))
}
}