2 * Copyright (C) 2017 Igalia S.L.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "CommandResult.h"
29 #include <inspector/InspectorValues.h>
31 using namespace Inspector;
35 // These error codes are specified in JSON-RPC 2.0, Section 5.1.
36 enum ProtocolErrorCode {
38 InvalidRequest = -32600,
39 MethodNotFound = -32601,
40 InvalidParams = -32602,
41 InternalError = -32603,
45 CommandResult::CommandResult(RefPtr<InspectorValue>&& result, std::optional<ErrorCode> errorCode)
46 : m_errorCode(errorCode)
49 m_result = WTFMove(result);
56 RefPtr<InspectorObject> errorObject;
57 if (!result->asObject(errorObject))
61 if (!errorObject->getInteger("code", error))
64 if (!errorObject->getString("message", errorMessage))
68 case ProtocolErrorCode::ParseError:
69 case ProtocolErrorCode::InvalidRequest:
70 case ProtocolErrorCode::MethodNotFound:
71 case ProtocolErrorCode::InvalidParams:
72 case ProtocolErrorCode::InternalError:
73 m_errorCode = ErrorCode::UnknownError;
74 m_errorMessage = errorMessage;
76 case ProtocolErrorCode::ServerError: {
78 auto position = errorMessage.find(';');
79 if (position != notFound) {
80 errorName = errorMessage.substring(0, position);
81 m_errorMessage = errorMessage.substring(position + 1);
83 errorName = errorMessage;
85 if (errorName == "WindowNotFound")
86 m_errorCode = ErrorCode::NoSuchWindow;
87 else if (errorName == "FrameNotFound")
88 m_errorCode = ErrorCode::NoSuchFrame;
89 else if (errorName == "NotImplemented")
90 m_errorCode = ErrorCode::UnsupportedOperation;
91 else if (errorName == "JavaScriptError")
92 m_errorCode = ErrorCode::JavascriptError;
93 else if (errorName == "JavaScriptTimeout")
94 m_errorCode = ErrorCode::ScriptTimeout;
95 else if (errorName == "NodeNotFound")
96 m_errorCode = ErrorCode::StaleElementReference;
97 else if (errorName == "MissingParameter" || errorName == "InvalidParameter")
98 m_errorCode = ErrorCode::InvalidArgument;
99 else if (errorName == "InvalidElementState")
100 m_errorCode = ErrorCode::InvalidElementState;
101 else if (errorName == "InvalidSelector")
102 m_errorCode = ErrorCode::InvalidSelector;
103 else if (errorName == "Timeout")
104 m_errorCode = ErrorCode::Timeout;
111 CommandResult::CommandResult(ErrorCode errorCode, std::optional<String> errorMessage)
112 : m_errorCode(errorCode)
113 , m_errorMessage(errorMessage)
117 unsigned CommandResult::httpStatusCode() const
122 // ยง6.6 Handling Errors.
123 // https://www.w3.org/TR/webdriver/#handling-errors
124 switch (m_errorCode.value()) {
125 case ErrorCode::ElementClickIntercepted:
126 case ErrorCode::ElementNotInteractable:
127 case ErrorCode::InvalidArgument:
128 case ErrorCode::InvalidElementState:
129 case ErrorCode::InvalidSelector:
130 case ErrorCode::NoSuchElement:
131 case ErrorCode::NoSuchFrame:
132 case ErrorCode::NoSuchWindow:
133 case ErrorCode::StaleElementReference:
135 case ErrorCode::InvalidSessionID:
136 case ErrorCode::UnknownCommand:
138 case ErrorCode::ScriptTimeout:
139 case ErrorCode::Timeout:
141 case ErrorCode::JavascriptError:
142 case ErrorCode::SessionNotCreated:
143 case ErrorCode::UnknownError:
144 case ErrorCode::UnsupportedOperation:
148 ASSERT_NOT_REACHED();
152 String CommandResult::errorString() const
156 switch (m_errorCode.value()) {
157 case ErrorCode::ElementClickIntercepted:
158 return ASCIILiteral("element click intercepted");
159 case ErrorCode::ElementNotInteractable:
160 return ASCIILiteral("element not interactable");
161 case ErrorCode::InvalidArgument:
162 return ASCIILiteral("invalid argument");
163 case ErrorCode::InvalidElementState:
164 return ASCIILiteral("invalid element state");
165 case ErrorCode::InvalidSelector:
166 return ASCIILiteral("invalid selector");
167 case ErrorCode::InvalidSessionID:
168 return ASCIILiteral("invalid session id");
169 case ErrorCode::JavascriptError:
170 return ASCIILiteral("javascript error");
171 case ErrorCode::NoSuchElement:
172 return ASCIILiteral("no such element");
173 case ErrorCode::NoSuchFrame:
174 return ASCIILiteral("no such frame");
175 case ErrorCode::NoSuchWindow:
176 return ASCIILiteral("no such window");
177 case ErrorCode::ScriptTimeout:
178 return ASCIILiteral("script timeout");
179 case ErrorCode::SessionNotCreated:
180 return ASCIILiteral("session not created");
181 case ErrorCode::StaleElementReference:
182 return ASCIILiteral("stale element reference");
183 case ErrorCode::Timeout:
184 return ASCIILiteral("timeout");
185 case ErrorCode::UnknownCommand:
186 return ASCIILiteral("unknown command");
187 case ErrorCode::UnknownError:
188 return ASCIILiteral("unknown error");
189 case ErrorCode::UnsupportedOperation:
190 return ASCIILiteral("unsupported operation");
193 ASSERT_NOT_REACHED();
194 return emptyString();
197 } // namespace WebDriver