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