Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/selenium/webdriver/remote/errorhandler.py
1864 views
1
# Licensed to the Software Freedom Conservancy (SFC) under one
2
# or more contributor license agreements. See the NOTICE file
3
# distributed with this work for additional information
4
# regarding copyright ownership. The SFC licenses this file
5
# to you under the Apache License, Version 2.0 (the
6
# "License"); you may not use this file except in compliance
7
# with the License. You may obtain a copy of the License at
8
#
9
# http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing,
12
# software distributed under the License is distributed on an
13
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
# KIND, either express or implied. See the License for the
15
# specific language governing permissions and limitations
16
# under the License.
17
18
import json
19
from typing import Any
20
21
from selenium.common.exceptions import (
22
DetachedShadowRootException,
23
ElementClickInterceptedException,
24
ElementNotInteractableException,
25
ElementNotSelectableException,
26
ElementNotVisibleException,
27
ImeActivationFailedException,
28
ImeNotAvailableException,
29
InsecureCertificateException,
30
InvalidArgumentException,
31
InvalidCookieDomainException,
32
InvalidCoordinatesException,
33
InvalidElementStateException,
34
InvalidSelectorException,
35
InvalidSessionIdException,
36
JavascriptException,
37
MoveTargetOutOfBoundsException,
38
NoAlertPresentException,
39
NoSuchCookieException,
40
NoSuchElementException,
41
NoSuchFrameException,
42
NoSuchShadowRootException,
43
NoSuchWindowException,
44
ScreenshotException,
45
SessionNotCreatedException,
46
StaleElementReferenceException,
47
TimeoutException,
48
UnableToSetCookieException,
49
UnexpectedAlertPresentException,
50
UnknownMethodException,
51
WebDriverException,
52
)
53
54
55
class ExceptionMapping:
56
"""
57
:Maps each errorcode in ErrorCode object to corresponding exception
58
Please refer to https://www.w3.org/TR/webdriver2/#errors for w3c specification
59
"""
60
61
NO_SUCH_ELEMENT = NoSuchElementException
62
NO_SUCH_FRAME = NoSuchFrameException
63
NO_SUCH_SHADOW_ROOT = NoSuchShadowRootException
64
STALE_ELEMENT_REFERENCE = StaleElementReferenceException
65
ELEMENT_NOT_VISIBLE = ElementNotVisibleException
66
INVALID_ELEMENT_STATE = InvalidElementStateException
67
UNKNOWN_ERROR = WebDriverException
68
ELEMENT_IS_NOT_SELECTABLE = ElementNotSelectableException
69
JAVASCRIPT_ERROR = JavascriptException
70
TIMEOUT = TimeoutException
71
NO_SUCH_WINDOW = NoSuchWindowException
72
INVALID_COOKIE_DOMAIN = InvalidCookieDomainException
73
UNABLE_TO_SET_COOKIE = UnableToSetCookieException
74
UNEXPECTED_ALERT_OPEN = UnexpectedAlertPresentException
75
NO_ALERT_OPEN = NoAlertPresentException
76
SCRIPT_TIMEOUT = TimeoutException
77
IME_NOT_AVAILABLE = ImeNotAvailableException
78
IME_ENGINE_ACTIVATION_FAILED = ImeActivationFailedException
79
INVALID_SELECTOR = InvalidSelectorException
80
SESSION_NOT_CREATED = SessionNotCreatedException
81
MOVE_TARGET_OUT_OF_BOUNDS = MoveTargetOutOfBoundsException
82
INVALID_XPATH_SELECTOR = InvalidSelectorException
83
INVALID_XPATH_SELECTOR_RETURN_TYPER = InvalidSelectorException
84
ELEMENT_NOT_INTERACTABLE = ElementNotInteractableException
85
INSECURE_CERTIFICATE = InsecureCertificateException
86
INVALID_ARGUMENT = InvalidArgumentException
87
INVALID_COORDINATES = InvalidCoordinatesException
88
INVALID_SESSION_ID = InvalidSessionIdException
89
NO_SUCH_COOKIE = NoSuchCookieException
90
UNABLE_TO_CAPTURE_SCREEN = ScreenshotException
91
ELEMENT_CLICK_INTERCEPTED = ElementClickInterceptedException
92
UNKNOWN_METHOD = UnknownMethodException
93
DETACHED_SHADOW_ROOT = DetachedShadowRootException
94
95
96
class ErrorCode:
97
"""Error codes defined in the WebDriver wire protocol."""
98
99
# Keep in sync with org.openqa.selenium.remote.ErrorCodes and errorcodes.h
100
SUCCESS = 0
101
NO_SUCH_ELEMENT = [7, "no such element"]
102
NO_SUCH_FRAME = [8, "no such frame"]
103
NO_SUCH_SHADOW_ROOT = ["no such shadow root"]
104
UNKNOWN_COMMAND = [9, "unknown command"]
105
STALE_ELEMENT_REFERENCE = [10, "stale element reference"]
106
ELEMENT_NOT_VISIBLE = [11, "element not visible"]
107
INVALID_ELEMENT_STATE = [12, "invalid element state"]
108
UNKNOWN_ERROR = [13, "unknown error"]
109
ELEMENT_IS_NOT_SELECTABLE = [15, "element not selectable"]
110
JAVASCRIPT_ERROR = [17, "javascript error"]
111
XPATH_LOOKUP_ERROR = [19, "invalid selector"]
112
TIMEOUT = [21, "timeout"]
113
NO_SUCH_WINDOW = [23, "no such window"]
114
INVALID_COOKIE_DOMAIN = [24, "invalid cookie domain"]
115
UNABLE_TO_SET_COOKIE = [25, "unable to set cookie"]
116
UNEXPECTED_ALERT_OPEN = [26, "unexpected alert open"]
117
NO_ALERT_OPEN = [27, "no such alert"]
118
SCRIPT_TIMEOUT = [28, "script timeout"]
119
INVALID_ELEMENT_COORDINATES = [29, "invalid element coordinates"]
120
IME_NOT_AVAILABLE = [30, "ime not available"]
121
IME_ENGINE_ACTIVATION_FAILED = [31, "ime engine activation failed"]
122
INVALID_SELECTOR = [32, "invalid selector"]
123
SESSION_NOT_CREATED = [33, "session not created"]
124
MOVE_TARGET_OUT_OF_BOUNDS = [34, "move target out of bounds"]
125
INVALID_XPATH_SELECTOR = [51, "invalid selector"]
126
INVALID_XPATH_SELECTOR_RETURN_TYPER = [52, "invalid selector"]
127
128
ELEMENT_NOT_INTERACTABLE = [60, "element not interactable"]
129
INSECURE_CERTIFICATE = ["insecure certificate"]
130
INVALID_ARGUMENT = [61, "invalid argument"]
131
INVALID_COORDINATES = ["invalid coordinates"]
132
INVALID_SESSION_ID = ["invalid session id"]
133
NO_SUCH_COOKIE = [62, "no such cookie"]
134
UNABLE_TO_CAPTURE_SCREEN = [63, "unable to capture screen"]
135
ELEMENT_CLICK_INTERCEPTED = [64, "element click intercepted"]
136
UNKNOWN_METHOD = ["unknown method exception"]
137
DETACHED_SHADOW_ROOT = [65, "detached shadow root"]
138
139
METHOD_NOT_ALLOWED = [405, "unsupported operation"]
140
141
142
class ErrorHandler:
143
"""Handles errors returned by the WebDriver server."""
144
145
def check_response(self, response: dict[str, Any]) -> None:
146
"""Checks that a JSON response from the WebDriver does not have an
147
error.
148
149
:Args:
150
- response - The JSON response from the WebDriver server as a dictionary
151
object.
152
153
:Raises: If the response contains an error message.
154
"""
155
status = response.get("status", None)
156
if not status or status == ErrorCode.SUCCESS:
157
return
158
value = None
159
message = response.get("message", "")
160
screen: str = response.get("screen", "")
161
stacktrace = None
162
if isinstance(status, int):
163
value_json = response.get("value", None)
164
if value_json and isinstance(value_json, str):
165
try:
166
value = json.loads(value_json)
167
if isinstance(value, dict):
168
if len(value) == 1:
169
value = value["value"]
170
status = value.get("error", None)
171
if not status:
172
status = value.get("status", ErrorCode.UNKNOWN_ERROR)
173
message = value.get("value") or value.get("message")
174
if not isinstance(message, str):
175
value = message
176
message = message.get("message") if isinstance(message, dict) else None
177
else:
178
message = value.get("message", None)
179
except ValueError:
180
pass
181
182
exception_class: type[WebDriverException]
183
e = ErrorCode()
184
error_codes = [item for item in dir(e) if not item.startswith("__")]
185
for error_code in error_codes:
186
error_info = getattr(ErrorCode, error_code)
187
if isinstance(error_info, list) and status in error_info:
188
exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
189
break
190
else:
191
exception_class = WebDriverException
192
193
if not value:
194
value = response["value"]
195
if isinstance(value, str):
196
raise exception_class(value)
197
if message == "" and "message" in value:
198
message = value["message"]
199
200
screen = None # type: ignore[assignment]
201
if "screen" in value:
202
screen = value["screen"]
203
204
stacktrace = None
205
st_value = value.get("stackTrace") or value.get("stacktrace")
206
if st_value:
207
if isinstance(st_value, str):
208
stacktrace = st_value.split("\n")
209
else:
210
stacktrace = []
211
try:
212
for frame in st_value:
213
line = frame.get("lineNumber", "")
214
file = frame.get("fileName", "<anonymous>")
215
if line:
216
file = f"{file}:{line}"
217
meth = frame.get("methodName", "<anonymous>")
218
if "className" in frame:
219
meth = f"{frame['className']}.{meth}"
220
msg = " at %s (%s)"
221
msg = msg % (meth, file)
222
stacktrace.append(msg)
223
except TypeError:
224
pass
225
if exception_class == UnexpectedAlertPresentException:
226
alert_text = None
227
if "data" in value:
228
alert_text = value["data"].get("text")
229
elif "alert" in value:
230
alert_text = value["alert"].get("text")
231
raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here
232
raise exception_class(message, screen, stacktrace)
233
234