Commit 6b0d1e43 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

Forward error information from devtools to the server.

This change is meant to provide extra information to debug
UNEXPECTED_JS_ERROR and UNEXPECTED_ERROR we get from time to time in
production.

Bug: b/139791239
Change-Id: I74b4d284a70e9a4082ce64b493f1fdd6c0a7488a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1771910
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693063}
parent 16e76d33
...@@ -46,7 +46,9 @@ void Domain::RegisterEventHandlersIfNeeded() { ...@@ -46,7 +46,9 @@ void Domain::RegisterEventHandlersIfNeeded() {
{% for command in domain.commands %} {% for command in domain.commands %}
{% set class_name = 'ExperimentalDomain' if command.experimental else 'Domain' %} {% set class_name = 'ExperimentalDomain' if command.experimental else 'Domain' %}
{% set method_name = command.name | sanitize_literal | to_title_case %} {% set method_name = command.name | sanitize_literal | to_title_case %}
void {{class_name}}::{{method_name}}(std::unique_ptr<{{method_name}}Params> params, base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback) { void {{class_name}}::{{method_name}}(
std::unique_ptr<{{method_name}}Params> params,
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback) {
dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), base::BindOnce(&Domain::Handle{{method_name}}Response, std::move(callback))); dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), base::BindOnce(&Domain::Handle{{method_name}}Response, std::move(callback)));
} }
{# Generate convenience methods that take the required parameters directly. #} {# Generate convenience methods that take the required parameters directly. #}
...@@ -64,7 +66,7 @@ void {{class_name}}::{{method_name}}({##} ...@@ -64,7 +66,7 @@ void {{class_name}}::{{method_name}}({##}
{% endfor %} {% endfor %}
{% if command.get("parameters", []) and not command.parameters[0].get("optional", False) %}, {% endif %}{# -#} {% if command.get("parameters", []) and not command.parameters[0].get("optional", False) %}, {% endif %}{# -#}
{% if command.get("returns", []) -%} {% if command.get("returns", []) -%}
base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback{##} base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback{##}
{% else -%} {% else -%}
base::OnceClosure callback{##} base::OnceClosure callback{##}
{% endif %}) { {% endif %}) {
...@@ -99,18 +101,22 @@ void {{class_name}}::{{method_name}}(std::unique_ptr<{{method_name}}Params> para ...@@ -99,18 +101,22 @@ void {{class_name}}::{{method_name}}(std::unique_ptr<{{method_name}}Params> para
{% set method_name = command.name | sanitize_literal | to_title_case %} {% set method_name = command.name | sanitize_literal | to_title_case %}
// static // static
void Domain::Handle{{method_name}}Response(base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback, const base::Value& response) { void Domain::Handle{{method_name}}Response(
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback,
const MessageDispatcher::ReplyStatus& reply_status,
const base::Value& response) {
if (callback.is_null()) if (callback.is_null())
return; return;
// This is an error response. // This is an error response.
if (response.is_none()) { if (response.is_none()) {
std::move(callback).Run(nullptr); std::move(callback).Run(reply_status, nullptr);
return; return;
} }
ErrorReporter errors; ErrorReporter errors;
std::unique_ptr<{{method_name}}Result> result = {{method_name}}Result::Parse(response, &errors); std::unique_ptr<{{method_name}}Result> result = {{method_name}}Result::Parse(response, &errors);
DCHECK(!errors.HasErrors()) << errors.ToString(); DCHECK(!errors.HasErrors()) << errors.ToString();
std::move(callback).Run(std::move(result)); std::move(callback).Run(reply_status, std::move(result));
} }
{% endfor %} {% endfor %}
{% if "events" in domain %} {% if "events" in domain %}
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
{% if command.description %} {% if command.description %}
// {{ command.description.replace('\n', '\n // ') }} // {{ command.description.replace('\n', '\n // ') }}
{% endif %} {% endif %}
void {{method_name}}(std::unique_ptr<{{method_name}}Params> params, base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback = base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)>()); void {{method_name}}(std::unique_ptr<{{method_name}}Params> params, base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback = base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)>());
{# Generate convenience methods that take the required parameters directly. #} {# Generate convenience methods that take the required parameters directly. #}
{# Don't generate these for experimental commands. #} {# Don't generate these for experimental commands. #}
{% if "parameters" in command and not command.experimental %} {% if "parameters" in command and not command.experimental %}
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
{% endfor %} {% endfor %}
{% if command.get("parameters", []) and not command.parameters[0].get("optional", False) %}, {% endif %}{# -#} {% if command.get("parameters", []) and not command.parameters[0].get("optional", False) %}, {% endif %}{# -#}
{% if command.get("returns", []) -%} {% if command.get("returns", []) -%}
base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback = base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)>(){##} base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback = base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)>(){##}
{% else -%} {% else -%}
base::OnceClosure callback = base::OnceClosure(){##} base::OnceClosure callback = base::OnceClosure(){##}
{% endif %}); {% endif %});
...@@ -108,7 +108,10 @@ class Domain { ...@@ -108,7 +108,10 @@ class Domain {
{% for command in domain.commands %} {% for command in domain.commands %}
{% if not "returns" in command %}{% continue %}{% endif %} {% if not "returns" in command %}{% continue %}{% endif %}
{% set method_name = command.name | sanitize_literal | to_title_case %} {% set method_name = command.name | sanitize_literal | to_title_case %}
static void Handle{{method_name}}Response(base::OnceCallback<void(std::unique_ptr<{{method_name}}Result>)> callback, const base::Value& response); static void Handle{{method_name}}Response(
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback,
const MessageDispatcher::ReplyStatus& reply_status,
const base::Value& response);
{% endfor %} {% endfor %}
{# Generate event dispatchers. #} {# Generate event dispatchers. #}
......
...@@ -56,7 +56,7 @@ network::Domain* DevtoolsClient::GetNetwork() { ...@@ -56,7 +56,7 @@ network::Domain* DevtoolsClient::GetNetwork() {
void DevtoolsClient::SendMessage( void DevtoolsClient::SendMessage(
const char* method, const char* method,
std::unique_ptr<base::Value> params, std::unique_ptr<base::Value> params,
base::OnceCallback<void(const base::Value&)> callback) { base::OnceCallback<void(const ReplyStatus&, const base::Value&)> callback) {
SendMessageWithParams(method, std::move(params), std::move(callback)); SendMessageWithParams(method, std::move(params), std::move(callback));
} }
...@@ -132,6 +132,7 @@ bool DevtoolsClient::DispatchMessageReply( ...@@ -132,6 +132,7 @@ bool DevtoolsClient::DispatchMessageReply(
pending_messages_.erase(it); pending_messages_.erase(it);
if (!callback.callback_with_result.is_null()) { if (!callback.callback_with_result.is_null()) {
const base::DictionaryValue* result_dict; const base::DictionaryValue* result_dict;
ReplyStatus status;
if (message_dict.GetDictionary("result", &result_dict)) { if (message_dict.GetDictionary("result", &result_dict)) {
if (browser_main_thread_) { if (browser_main_thread_) {
browser_main_thread_->PostTask( browser_main_thread_->PostTask(
...@@ -139,22 +140,24 @@ bool DevtoolsClient::DispatchMessageReply( ...@@ -139,22 +140,24 @@ bool DevtoolsClient::DispatchMessageReply(
base::BindOnce( base::BindOnce(
&DevtoolsClient::DispatchMessageReplyWithResultTask, &DevtoolsClient::DispatchMessageReplyWithResultTask,
weak_ptr_factory_.GetWeakPtr(), std::move(owning_message), weak_ptr_factory_.GetWeakPtr(), std::move(owning_message),
std::move(callback.callback_with_result), result_dict)); std::move(callback.callback_with_result), status, result_dict));
} else { } else {
std::move(callback.callback_with_result).Run(*result_dict); std::move(callback.callback_with_result).Run(status, *result_dict);
} }
} else if (message_dict.GetDictionary("error", &result_dict)) { } else if (message_dict.GetDictionary("error", &result_dict)) {
auto null_value = std::make_unique<base::Value>(); auto null_value = std::make_unique<base::Value>();
DLOG(ERROR) << "Error in method call result: " << *result_dict; DLOG(ERROR) << "Error in method call result: " << *result_dict;
FillReplyStatusFromErrorDict(&status, *result_dict);
if (browser_main_thread_) { if (browser_main_thread_) {
browser_main_thread_->PostTask( browser_main_thread_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(&DevtoolsClient::DispatchMessageReplyWithResultTask,
&DevtoolsClient::DispatchMessageReplyWithResultTask, weak_ptr_factory_.GetWeakPtr(),
weak_ptr_factory_.GetWeakPtr(), std::move(null_value), std::move(null_value),
std::move(callback.callback_with_result), null_value.get())); std::move(callback.callback_with_result), status,
null_value.get()));
} else { } else {
std::move(callback.callback_with_result).Run(*null_value); std::move(callback.callback_with_result).Run(status, *null_value);
} }
} else { } else {
NOTREACHED() << "Reply has neither result nor error"; NOTREACHED() << "Reply has neither result nor error";
...@@ -180,9 +183,10 @@ bool DevtoolsClient::DispatchMessageReply( ...@@ -180,9 +183,10 @@ bool DevtoolsClient::DispatchMessageReply(
void DevtoolsClient::DispatchMessageReplyWithResultTask( void DevtoolsClient::DispatchMessageReplyWithResultTask(
std::unique_ptr<base::Value> owning_message, std::unique_ptr<base::Value> owning_message,
base::OnceCallback<void(const base::Value&)> callback, base::OnceCallback<void(const ReplyStatus&, const base::Value&)> callback,
const ReplyStatus& reply_status,
const base::Value* result_dict) { const base::Value* result_dict) {
std::move(callback).Run(*result_dict); std::move(callback).Run(reply_status, *result_dict);
} }
bool DevtoolsClient::DispatchEvent(std::unique_ptr<base::Value> owning_message, bool DevtoolsClient::DispatchEvent(std::unique_ptr<base::Value> owning_message,
...@@ -227,6 +231,24 @@ void DevtoolsClient::DispatchEventTask( ...@@ -227,6 +231,24 @@ void DevtoolsClient::DispatchEventTask(
event_handler->Run(*result_dict); event_handler->Run(*result_dict);
} }
void DevtoolsClient::FillReplyStatusFromErrorDict(
ReplyStatus* status,
const base::DictionaryValue& error_dict) {
const base::Value* code;
if (error_dict.Get("code", &code) && code->is_int()) {
status->error_code = code->GetInt();
} else {
status->error_code = -1; // unknown error code
}
const base::Value* message;
if (error_dict.Get("message", &message) && message->is_string()) {
status->error_message = message->GetString();
} else {
status->error_message = "unknown";
}
}
void DevtoolsClient::AgentHostClosed(content::DevToolsAgentHost* agent_host) { void DevtoolsClient::AgentHostClosed(content::DevToolsAgentHost* agent_host) {
// Agent host is not expected to be closed when this object is alive. // Agent host is not expected to be closed when this object is alive.
renderer_crashed_ = true; renderer_crashed_ = true;
...@@ -240,7 +262,7 @@ DevtoolsClient::Callback::Callback(base::OnceClosure callback) ...@@ -240,7 +262,7 @@ DevtoolsClient::Callback::Callback(base::OnceClosure callback)
: callback(std::move(callback)) {} : callback(std::move(callback)) {}
DevtoolsClient::Callback::Callback( DevtoolsClient::Callback::Callback(
base::OnceCallback<void(const base::Value&)> callback) base::OnceCallback<void(const ReplyStatus&, const base::Value&)> callback)
: callback_with_result(std::move(callback)) {} : callback_with_result(std::move(callback)) {}
DevtoolsClient::Callback::~Callback() = default; DevtoolsClient::Callback::~Callback() = default;
......
...@@ -44,7 +44,8 @@ class DevtoolsClient : public MessageDispatcher, ...@@ -44,7 +44,8 @@ class DevtoolsClient : public MessageDispatcher,
void SendMessage( void SendMessage(
const char* method, const char* method,
std::unique_ptr<base::Value> params, std::unique_ptr<base::Value> params,
base::OnceCallback<void(const base::Value&)> callback) override; base::OnceCallback<void(const ReplyStatus&, const base::Value&)> callback)
override;
void SendMessage(const char* method, void SendMessage(const char* method,
std::unique_ptr<base::Value> params, std::unique_ptr<base::Value> params,
base::OnceClosure callback) override; base::OnceClosure callback) override;
...@@ -64,13 +65,15 @@ class DevtoolsClient : public MessageDispatcher, ...@@ -64,13 +65,15 @@ class DevtoolsClient : public MessageDispatcher,
Callback(); Callback();
Callback(Callback&& other); Callback(Callback&& other);
explicit Callback(base::OnceClosure callback); explicit Callback(base::OnceClosure callback);
explicit Callback(base::OnceCallback<void(const base::Value&)> callback); explicit Callback(base::OnceCallback<void(const ReplyStatus&,
const base::Value&)> callback);
~Callback(); ~Callback();
Callback& operator=(Callback&& other); Callback& operator=(Callback&& other);
base::OnceClosure callback; base::OnceClosure callback;
base::OnceCallback<void(const base::Value&)> callback_with_result; base::OnceCallback<void(const ReplyStatus&, const base::Value&)>
callback_with_result;
}; };
template <typename CallbackType> template <typename CallbackType>
...@@ -81,7 +84,8 @@ class DevtoolsClient : public MessageDispatcher, ...@@ -81,7 +84,8 @@ class DevtoolsClient : public MessageDispatcher,
const base::DictionaryValue& message_dict); const base::DictionaryValue& message_dict);
void DispatchMessageReplyWithResultTask( void DispatchMessageReplyWithResultTask(
std::unique_ptr<base::Value> owning_message, std::unique_ptr<base::Value> owning_message,
base::OnceCallback<void(const base::Value&)> callback, base::OnceCallback<void(const ReplyStatus&, const base::Value&)> callback,
const ReplyStatus& reply_status,
const base::Value* result_dict); const base::Value* result_dict);
bool DispatchEvent(std::unique_ptr<base::Value> owning_message, bool DispatchEvent(std::unique_ptr<base::Value> owning_message,
const base::DictionaryValue& message_dict); const base::DictionaryValue& message_dict);
...@@ -91,6 +95,8 @@ class DevtoolsClient : public MessageDispatcher, ...@@ -91,6 +95,8 @@ class DevtoolsClient : public MessageDispatcher,
void DispatchEventTask(std::unique_ptr<base::Value> owning_message, void DispatchEventTask(std::unique_ptr<base::Value> owning_message,
const EventHandler* event_handler, const EventHandler* event_handler,
const base::DictionaryValue* result_dict); const base::DictionaryValue* result_dict);
void FillReplyStatusFromErrorDict(ReplyStatus* status,
const base::DictionaryValue& error_dict);
scoped_refptr<content::DevToolsAgentHost> agent_host_; scoped_refptr<content::DevToolsAgentHost> agent_host_;
scoped_refptr<base::SequencedTaskRunner> browser_main_thread_; scoped_refptr<base::SequencedTaskRunner> browser_main_thread_;
......
...@@ -22,10 +22,24 @@ namespace autofill_assistant { ...@@ -22,10 +22,24 @@ namespace autofill_assistant {
// An internal interface for sending DevTools messages from the domain agents. // An internal interface for sending DevTools messages from the domain agents.
class MessageDispatcher { class MessageDispatcher {
public: public:
// Status of a SendMessage operation.
struct ReplyStatus {
// Error codes, as a number, -1 if error code is unknown.
//
// Possible values are listed on:
// src/third_party/inspector_protocol/lib/DispatcherBase_h.template
long error_code = 0;
std::string error_message;
bool is_ok() const { return error_code == 0; }
};
virtual void SendMessage( virtual void SendMessage(
const char* method, const char* method,
std::unique_ptr<base::Value> params, std::unique_ptr<base::Value> params,
base::OnceCallback<void(const base::Value&)> callback) = 0; base::OnceCallback<void(const ReplyStatus&, const base::Value&)>
callback) = 0;
virtual void SendMessage(const char* method, virtual void SendMessage(const char* method,
std::unique_ptr<base::Value> params, std::unique_ptr<base::Value> params,
base::OnceClosure callback) = 0; base::OnceClosure callback) = 0;
......
...@@ -565,6 +565,12 @@ message UnexpectedErrorInfoProto { ...@@ -565,6 +565,12 @@ message UnexpectedErrorInfoProto {
// JavaScript exception column number, within the js snippet that was sent to // JavaScript exception column number, within the js snippet that was sent to
// devtools runtime by the client, if reporting a JavaScript error. // devtools runtime by the client, if reporting a JavaScript error.
optional int32 js_exception_column_number = 5; optional int32 js_exception_column_number = 5;
// Error code returned by devtools, if any. 0 is considered a success.
optional int32 devtools_error_code = 6;
// Error message returned by devtools, if any.
optional string devtools_error_message = 7;
} }
// Message to report autofill related errors for debugging purposes. // Message to report autofill related errors for debugging purposes.
......
...@@ -148,8 +148,10 @@ void ElementFinder::SendResult(const ClientStatus& status) { ...@@ -148,8 +148,10 @@ void ElementFinder::SendResult(const ClientStatus& status) {
} }
void ElementFinder::OnGetDocumentElement( void ElementFinder::OnGetDocumentElement(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result) { std::unique_ptr<runtime::EvaluateResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << " Failed to get document root element."; DVLOG(1) << __func__ << " Failed to get document root element.";
SendResult(status); SendResult(status);
...@@ -218,6 +220,7 @@ void ElementFinder::RecursiveFindElement(const std::string& object_id, ...@@ -218,6 +220,7 @@ void ElementFinder::RecursiveFindElement(const std::string& object_id,
void ElementFinder::OnQuerySelectorAll( void ElementFinder::OnQuerySelectorAll(
size_t index, size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result) { if (!result) {
// It is possible for a document element to already exist, but not be // It is possible for a document element to already exist, but not be
...@@ -229,7 +232,8 @@ void ElementFinder::OnQuerySelectorAll( ...@@ -229,7 +232,8 @@ void ElementFinder::OnQuerySelectorAll(
SendResult(ClientStatus(ELEMENT_RESOLUTION_FAILED)); SendResult(ClientStatus(ELEMENT_RESOLUTION_FAILED));
return; return;
} }
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << ": Failed to query selector " << index << " of " DVLOG(1) << __func__ << ": Failed to query selector " << index << " of "
<< selector_; << selector_;
...@@ -282,10 +286,11 @@ void ElementFinder::OnQuerySelectorAll( ...@@ -282,10 +286,11 @@ void ElementFinder::OnQuerySelectorAll(
void ElementFinder::OnDescribeNodeForPseudoElement( void ElementFinder::OnDescribeNodeForPseudoElement(
dom::PseudoType pseudo_type, dom::PseudoType pseudo_type,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::DescribeNodeResult> result) { std::unique_ptr<dom::DescribeNodeResult> result) {
if (!result || !result->GetNode()) { if (!result || !result->GetNode()) {
DVLOG(1) << __func__ << " Failed to describe the node for pseudo element."; DVLOG(1) << __func__ << " Failed to describe the node for pseudo element.";
SendResult(UnexpectedErrorStatus(__FILE__, __LINE__)); SendResult(UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
...@@ -310,6 +315,7 @@ void ElementFinder::OnDescribeNodeForPseudoElement( ...@@ -310,6 +315,7 @@ void ElementFinder::OnDescribeNodeForPseudoElement(
} }
void ElementFinder::OnResolveNodeForPseudoElement( void ElementFinder::OnResolveNodeForPseudoElement(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::ResolveNodeResult> result) { std::unique_ptr<dom::ResolveNodeResult> result) {
if (result && result->GetObject() && result->GetObject()->HasObjectId()) { if (result && result->GetObject() && result->GetObject()->HasObjectId()) {
element_result_->object_id = result->GetObject()->GetObjectId(); element_result_->object_id = result->GetObject()->GetObjectId();
...@@ -320,10 +326,11 @@ void ElementFinder::OnResolveNodeForPseudoElement( ...@@ -320,10 +326,11 @@ void ElementFinder::OnResolveNodeForPseudoElement(
void ElementFinder::OnDescribeNode( void ElementFinder::OnDescribeNode(
const std::string& object_id, const std::string& object_id,
size_t index, size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::DescribeNodeResult> result) { std::unique_ptr<dom::DescribeNodeResult> result) {
if (!result || !result->GetNode()) { if (!result || !result->GetNode()) {
DVLOG(1) << __func__ << " Failed to describe the node."; DVLOG(1) << __func__ << " Failed to describe the node.";
SendResult(UnexpectedErrorStatus(__FILE__, __LINE__)); SendResult(UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
...@@ -354,7 +361,8 @@ void ElementFinder::OnDescribeNode( ...@@ -354,7 +361,8 @@ void ElementFinder::OnDescribeNode(
frame_name, node->GetContentDocument()->GetDocumentURL()); frame_name, node->GetContentDocument()->GetDocumentURL());
if (!element_result_->container_frame_host) { if (!element_result_->container_frame_host) {
DVLOG(1) << __func__ << " Failed to find corresponding owner frame."; DVLOG(1) << __func__ << " Failed to find corresponding owner frame.";
SendResult(UnexpectedErrorStatus(__FILE__, __LINE__)); SendResult(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
} else if (node->HasFrameId()) { } else if (node->HasFrameId()) {
...@@ -385,10 +393,11 @@ void ElementFinder::OnDescribeNode( ...@@ -385,10 +393,11 @@ void ElementFinder::OnDescribeNode(
void ElementFinder::OnResolveNode( void ElementFinder::OnResolveNode(
size_t index, size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::ResolveNodeResult> result) { std::unique_ptr<dom::ResolveNodeResult> result) {
if (!result || !result->GetObject() || !result->GetObject()->HasObjectId()) { if (!result || !result->GetObject() || !result->GetObject()->HasObjectId()) {
DVLOG(1) << __func__ << " Failed to resolve object id from backend id."; DVLOG(1) << __func__ << " Failed to resolve object id from backend id.";
SendResult(UnexpectedErrorStatus(__FILE__, __LINE__)); SendResult(UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "components/autofill_assistant/browser/client_status.h" #include "components/autofill_assistant/browser/client_status.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_dom.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_dom.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h"
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
#include "components/autofill_assistant/browser/selector.h" #include "components/autofill_assistant/browser/selector.h"
#include "components/autofill_assistant/browser/web/web_controller_worker.h" #include "components/autofill_assistant/browser/web/web_controller_worker.h"
...@@ -61,20 +62,26 @@ class ElementFinder : public WebControllerWorker { ...@@ -61,20 +62,26 @@ class ElementFinder : public WebControllerWorker {
private: private:
void SendResult(const ClientStatus& status); void SendResult(const ClientStatus& status);
void OnGetDocumentElement(std::unique_ptr<runtime::EvaluateResult> result); void OnGetDocumentElement(const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result);
void RecursiveFindElement(const std::string& object_id, size_t index); void RecursiveFindElement(const std::string& object_id, size_t index);
void OnQuerySelectorAll( void OnQuerySelectorAll(
size_t index, size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnDescribeNodeForPseudoElement( void OnDescribeNodeForPseudoElement(
dom::PseudoType pseudo_type, dom::PseudoType pseudo_type,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::DescribeNodeResult> result); std::unique_ptr<dom::DescribeNodeResult> result);
void OnResolveNodeForPseudoElement( void OnResolveNodeForPseudoElement(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::ResolveNodeResult> result); std::unique_ptr<dom::ResolveNodeResult> result);
void OnDescribeNode(const std::string& object_id, void OnDescribeNode(const std::string& object_id,
size_t index, size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::DescribeNodeResult> result); std::unique_ptr<dom::DescribeNodeResult> result);
void OnResolveNode(size_t index, void OnResolveNode(size_t index,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::ResolveNodeResult> result); std::unique_ptr<dom::ResolveNodeResult> result);
content::RenderFrameHost* FindCorrespondingRenderFrameHost( content::RenderFrameHost* FindCorrespondingRenderFrameHost(
std::string name, std::string name,
......
...@@ -69,6 +69,7 @@ void ElementPositionGetter::GetAndWaitBoxModelStable() { ...@@ -69,6 +69,7 @@ void ElementPositionGetter::GetAndWaitBoxModelStable() {
} }
void ElementPositionGetter::OnGetBoxModelForStableCheck( void ElementPositionGetter::OnGetBoxModelForStableCheck(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::GetBoxModelResult> result) { std::unique_ptr<dom::GetBoxModelResult> result) {
if (!result || !result->GetModel() || !result->GetModel()->GetContent()) { if (!result || !result->GetModel() || !result->GetModel()->GetContent()) {
DVLOG(1) << __func__ << " Failed to get box model."; DVLOG(1) << __func__ << " Failed to get box model.";
...@@ -137,8 +138,10 @@ void ElementPositionGetter::OnGetBoxModelForStableCheck( ...@@ -137,8 +138,10 @@ void ElementPositionGetter::OnGetBoxModelForStableCheck(
} }
void ElementPositionGetter::OnScrollIntoView( void ElementPositionGetter::OnScrollIntoView(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << " Failed to scroll the element: " << status; DVLOG(1) << __func__ << " Failed to scroll the element: " << status;
OnError(); OnError();
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/client_settings.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_dom.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_dom.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h"
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
#include "components/autofill_assistant/browser/selector.h" #include "components/autofill_assistant/browser/selector.h"
#include "components/autofill_assistant/browser/web/web_controller_worker.h" #include "components/autofill_assistant/browser/web/web_controller_worker.h"
...@@ -22,7 +23,6 @@ class RenderFrameHost; ...@@ -22,7 +23,6 @@ class RenderFrameHost;
} // namespace content } // namespace content
namespace autofill_assistant { namespace autofill_assistant {
class DevtoolsClient;
// Worker class to get an element's position in viewport coordinates when it is // Worker class to get an element's position in viewport coordinates when it is
// stable and the frame it belongs to has finished its visual update. // stable and the frame it belongs to has finished its visual update.
...@@ -49,8 +49,10 @@ class ElementPositionGetter : public WebControllerWorker { ...@@ -49,8 +49,10 @@ class ElementPositionGetter : public WebControllerWorker {
void OnVisualStateUpdatedCallback(bool success); void OnVisualStateUpdatedCallback(bool success);
void GetAndWaitBoxModelStable(); void GetAndWaitBoxModelStable();
void OnGetBoxModelForStableCheck( void OnGetBoxModelForStableCheck(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::GetBoxModelResult> result); std::unique_ptr<dom::GetBoxModelResult> result);
void OnScrollIntoView(std::unique_ptr<runtime::CallFunctionOnResult> result); void OnScrollIntoView(const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnResult(int x, int y); void OnResult(int x, int y);
void OnError(); void OnError();
......
...@@ -229,8 +229,10 @@ void AppendWaitForDocumentReadyStateFunction(std::string* out) { ...@@ -229,8 +229,10 @@ void AppendWaitForDocumentReadyStateFunction(std::string* out) {
template <typename T> template <typename T>
void OnWaitForDocumentReadyState( void OnWaitForDocumentReadyState(
base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> callback, base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<T> result) { std::unique_ptr<T> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
DVLOG_IF(1, !status.ok()) DVLOG_IF(1, !status.ok())
<< __func__ << " Failed to get document ready state."; << __func__ << " Failed to get document ready state.";
int ready_state; int ready_state;
...@@ -340,8 +342,10 @@ void WebController::OnScrollIntoView( ...@@ -340,8 +342,10 @@ void WebController::OnScrollIntoView(
std::unique_ptr<ElementFinder::Result> target_element, std::unique_ptr<ElementFinder::Result> target_element,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
ClickAction::ClickType click_type, ClickAction::ClickType click_type,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << " Failed to scroll the element."; DVLOG(1) << __func__ << " Failed to scroll the element.";
std::move(callback).Run(status); std::move(callback).Run(status);
...@@ -378,8 +382,10 @@ void WebController::OnScrollIntoView( ...@@ -378,8 +382,10 @@ void WebController::OnScrollIntoView(
void WebController::OnClickJS( void WebController::OnClickJS(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << " Failed to click (javascript) the element."; DVLOG(1) << __func__ << " Failed to click (javascript) the element.";
} }
...@@ -436,11 +442,13 @@ void WebController::OnDispatchPressMouseEvent( ...@@ -436,11 +442,13 @@ void WebController::OnDispatchPressMouseEvent(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
int x, int x,
int y, int y,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchMouseEventResult> result) { std::unique_ptr<input::DispatchMouseEventResult> result) {
if (!result) { if (!result) {
DVLOG(1) << __func__ DVLOG(1) << __func__
<< " Failed to dispatch mouse left button pressed event."; << " Failed to dispatch mouse left button pressed event.";
std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); std::move(callback).Run(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
...@@ -458,16 +466,25 @@ void WebController::OnDispatchPressMouseEvent( ...@@ -458,16 +466,25 @@ void WebController::OnDispatchPressMouseEvent(
void WebController::OnDispatchReleaseMouseEvent( void WebController::OnDispatchReleaseMouseEvent(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchMouseEventResult> result) { std::unique_ptr<input::DispatchMouseEventResult> result) {
if (!result) {
DVLOG(1) << __func__ << " Failed to dispatch release mouse event.";
std::move(callback).Run(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return;
}
std::move(callback).Run(OkClientStatus()); std::move(callback).Run(OkClientStatus());
} }
void WebController::OnDispatchTouchEventStart( void WebController::OnDispatchTouchEventStart(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchTouchEventResult> result) { std::unique_ptr<input::DispatchTouchEventResult> result) {
if (!result) { if (!result) {
DVLOG(1) << __func__ << " Failed to dispatch touch start event."; DVLOG(1) << __func__ << " Failed to dispatch touch start event.";
std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); std::move(callback).Run(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
...@@ -484,8 +501,14 @@ void WebController::OnDispatchTouchEventStart( ...@@ -484,8 +501,14 @@ void WebController::OnDispatchTouchEventStart(
void WebController::OnDispatchTouchEventEnd( void WebController::OnDispatchTouchEventEnd(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchTouchEventResult> result) { std::unique_ptr<input::DispatchTouchEventResult> result) {
DCHECK(result); if (!result) {
DVLOG(1) << __func__ << " Failed to dispatch touch end event.";
std::move(callback).Run(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return;
}
std::move(callback).Run(OkClientStatus()); std::move(callback).Run(OkClientStatus());
} }
...@@ -522,9 +545,10 @@ void WebController::WaitForWindowHeightChange( ...@@ -522,9 +545,10 @@ void WebController::WaitForWindowHeightChange(
void WebController::OnWaitForWindowHeightChange( void WebController::OnWaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result) { std::unique_ptr<runtime::EvaluateResult> result) {
std::move(callback).Run( std::move(callback).Run(
CheckJavaScriptResult(result.get(), __FILE__, __LINE__)); CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__));
} }
void WebController::GetDocumentReadyState( void WebController::GetDocumentReadyState(
...@@ -672,8 +696,10 @@ void WebController::OnWaitDocumentToBecomeInteractiveForFocusElement( ...@@ -672,8 +696,10 @@ void WebController::OnWaitDocumentToBecomeInteractiveForFocusElement(
void WebController::OnFocusElement( void WebController::OnFocusElement(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
DVLOG_IF(1, !status.ok()) << __func__ << " Failed to focus on element."; DVLOG_IF(1, !status.ok()) << __func__ << " Failed to focus on element.";
std::move(callback).Run(status); std::move(callback).Run(status);
} }
...@@ -728,8 +754,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm( ...@@ -728,8 +754,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm(
const autofill::FormFieldData& form_field) { const autofill::FormFieldData& form_field) {
if (form_data.fields.empty()) { if (form_data.fields.empty()) {
DVLOG(1) << __func__ << " Failed to get form data to fill form."; DVLOG(1) << __func__ << " Failed to get form data to fill form.";
std::move(callback).Run( std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__));
UnexpectedErrorStatus(__FILE__, __LINE__)); // unexpected
return; return;
} }
...@@ -737,8 +762,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm( ...@@ -737,8 +762,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm(
ContentAutofillDriver::GetForRenderFrameHost(container_frame_host); ContentAutofillDriver::GetForRenderFrameHost(container_frame_host);
if (!driver) { if (!driver) {
DVLOG(1) << __func__ << " Failed to get the autofill driver."; DVLOG(1) << __func__ << " Failed to get the autofill driver.";
std::move(callback).Run( std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__));
UnexpectedErrorStatus(__FILE__, __LINE__)); // unexpected
return; return;
} }
...@@ -812,8 +836,10 @@ void WebController::OnFindElementForSelectOption( ...@@ -812,8 +836,10 @@ void WebController::OnFindElementForSelectOption(
void WebController::OnSelectOption( void WebController::OnSelectOption(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(1) << __func__ << " Failed to select option."; DVLOG(1) << __func__ << " Failed to select option.";
std::move(callback).Run(status); std::move(callback).Run(status);
...@@ -821,7 +847,8 @@ void WebController::OnSelectOption( ...@@ -821,7 +847,8 @@ void WebController::OnSelectOption(
} }
bool found; bool found;
if (!SafeGetBool(result->GetResult(), &found)) { if (!SafeGetBool(result->GetResult(), &found)) {
std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); std::move(callback).Run(
UnexpectedDevtoolsErrorStatus(reply_status, __FILE__, __LINE__));
return; return;
} }
if (!found) { if (!found) {
...@@ -870,8 +897,10 @@ void WebController::OnFindElementForHighlightElement( ...@@ -870,8 +897,10 @@ void WebController::OnFindElementForHighlightElement(
void WebController::OnHighlightElement( void WebController::OnHighlightElement(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
DVLOG_IF(1, !status.ok()) << __func__ << " Failed to highlight element."; DVLOG_IF(1, !status.ok()) << __func__ << " Failed to highlight element.";
std::move(callback).Run(status); std::move(callback).Run(status);
} }
...@@ -921,9 +950,11 @@ void WebController::OnFindElementForGetFieldValue( ...@@ -921,9 +950,11 @@ void WebController::OnFindElementForGetFieldValue(
void WebController::OnGetValueAttribute( void WebController::OnGetValueAttribute(
base::OnceCallback<void(bool, const std::string&)> callback, base::OnceCallback<void(bool, const std::string&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
std::string value; std::string value;
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
// Read the result returned from Javascript code. // Read the result returned from Javascript code.
DVLOG_IF(1, !status.ok()) DVLOG_IF(1, !status.ok())
<< __func__ << "Failed to get attribute value: " << status; << __func__ << "Failed to get attribute value: " << status;
...@@ -1090,9 +1121,10 @@ void WebController::OnFindElementForSetFieldValue( ...@@ -1090,9 +1121,10 @@ void WebController::OnFindElementForSetFieldValue(
void WebController::OnSetValueAttribute( void WebController::OnSetValueAttribute(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
std::move(callback).Run( std::move(callback).Run(
CheckJavaScriptResult(result.get(), __FILE__, __LINE__)); CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__));
} }
void WebController::SetAttribute( void WebController::SetAttribute(
...@@ -1149,9 +1181,10 @@ void WebController::OnFindElementForSetAttribute( ...@@ -1149,9 +1181,10 @@ void WebController::OnFindElementForSetAttribute(
void WebController::OnSetAttribute( void WebController::OnSetAttribute(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
std::move(callback).Run( std::move(callback).Run(
CheckJavaScriptResult(result.get(), __FILE__, __LINE__)); CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__));
} }
void WebController::SendKeyboardInput( void WebController::SendKeyboardInput(
...@@ -1219,8 +1252,10 @@ void WebController::GetVisualViewport( ...@@ -1219,8 +1252,10 @@ void WebController::GetVisualViewport(
void WebController::OnGetVisualViewport( void WebController::OnGetVisualViewport(
base::OnceCallback<void(bool, const RectF&)> callback, base::OnceCallback<void(bool, const RectF&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result) { std::unique_ptr<runtime::EvaluateResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok() || !result->GetResult()->HasValue() || if (!status.ok() || !result->GetResult()->HasValue() ||
!result->GetResult()->GetValue()->is_list() || !result->GetResult()->GetValue()->is_list() ||
result->GetResult()->GetValue()->GetList().size() != 4u) { result->GetResult()->GetValue()->GetList().size() != 4u) {
...@@ -1282,8 +1317,10 @@ void WebController::OnFindElementForPosition( ...@@ -1282,8 +1317,10 @@ void WebController::OnFindElementForPosition(
void WebController::OnGetElementPositionResult( void WebController::OnGetElementPositionResult(
base::OnceCallback<void(bool, const RectF&)> callback, base::OnceCallback<void(bool, const RectF&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok() || !result->GetResult()->HasValue() || if (!status.ok() || !result->GetResult()->HasValue() ||
!result->GetResult()->GetValue()->is_list() || !result->GetResult()->GetValue()->is_list() ||
result->GetResult()->GetValue()->GetList().size() != 4u) { result->GetResult()->GetValue()->GetList().size() != 4u) {
...@@ -1327,8 +1364,10 @@ void WebController::OnFindElementForGetOuterHtml( ...@@ -1327,8 +1364,10 @@ void WebController::OnFindElementForGetOuterHtml(
void WebController::OnGetOuterHtml( void WebController::OnGetOuterHtml(
base::OnceCallback<void(const ClientStatus&, const std::string&)> callback, base::OnceCallback<void(const ClientStatus&, const std::string&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok()) { if (!status.ok()) {
DVLOG(2) << __func__ << " Failed to get HTML content for GetOuterHtml"; DVLOG(2) << __func__ << " Failed to get HTML content for GetOuterHtml";
std::move(callback).Run(status, ""); std::move(callback).Run(status, "");
...@@ -1358,8 +1397,10 @@ void WebController::OnWaitForDocumentToBecomeInteractive( ...@@ -1358,8 +1397,10 @@ void WebController::OnWaitForDocumentToBecomeInteractive(
int remaining_rounds, int remaining_rounds,
std::string object_id, std::string object_id,
base::OnceCallback<void(bool)> callback, base::OnceCallback<void(bool)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result) { std::unique_ptr<runtime::CallFunctionOnResult> result) {
ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); ClientStatus status =
CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
if (!status.ok() || remaining_rounds <= 0) { if (!status.ok() || remaining_rounds <= 0) {
DVLOG(1) << __func__ DVLOG(1) << __func__
<< " Failed to wait for the document to become interactive with " << " Failed to wait for the document to become interactive with "
......
...@@ -237,10 +237,12 @@ class WebController { ...@@ -237,10 +237,12 @@ class WebController {
ClickAction::ClickType click_type, ClickAction::ClickType click_type,
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
void OnClickJS(base::OnceCallback<void(const ClientStatus&)> callback, void OnClickJS(base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnScrollIntoView(std::unique_ptr<ElementFinder::Result> target_element, void OnScrollIntoView(std::unique_ptr<ElementFinder::Result> target_element,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
ClickAction::ClickType click_type, ClickAction::ClickType click_type,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void TapOrClickOnCoordinates( void TapOrClickOnCoordinates(
ElementPositionGetter* getter_to_release, ElementPositionGetter* getter_to_release,
...@@ -253,21 +255,26 @@ class WebController { ...@@ -253,21 +255,26 @@ class WebController {
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
int x, int x,
int y, int y,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchMouseEventResult> result); std::unique_ptr<input::DispatchMouseEventResult> result);
void OnDispatchReleaseMouseEvent( void OnDispatchReleaseMouseEvent(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchMouseEventResult> result); std::unique_ptr<input::DispatchMouseEventResult> result);
void OnDispatchTouchEventStart( void OnDispatchTouchEventStart(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchTouchEventResult> result); std::unique_ptr<input::DispatchTouchEventResult> result);
void OnDispatchTouchEventEnd( void OnDispatchTouchEventEnd(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<input::DispatchTouchEventResult> result); std::unique_ptr<input::DispatchTouchEventResult> result);
void OnFindElementForCheck(base::OnceCallback<void(bool)> callback, void OnFindElementForCheck(base::OnceCallback<void(bool)> callback,
const ClientStatus& status, const ClientStatus& status,
std::unique_ptr<ElementFinder::Result> result); std::unique_ptr<ElementFinder::Result> result);
void OnWaitForWindowHeightChange( void OnWaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result); std::unique_ptr<runtime::EvaluateResult> result);
// Find the element given by |selector|. If multiple elements match // Find the element given by |selector|. If multiple elements match
...@@ -303,6 +310,7 @@ class WebController { ...@@ -303,6 +310,7 @@ class WebController {
std::unique_ptr<ElementFinder::Result> target_element, std::unique_ptr<ElementFinder::Result> target_element,
bool result); bool result);
void OnFocusElement(base::OnceCallback<void(const ClientStatus&)> callback, void OnFocusElement(base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForSelectOption( void OnFindElementForSelectOption(
const std::string& selected_option, const std::string& selected_option,
...@@ -310,6 +318,7 @@ class WebController { ...@@ -310,6 +318,7 @@ class WebController {
const ClientStatus& status, const ClientStatus& status,
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnSelectOption(base::OnceCallback<void(const ClientStatus&)> callback, void OnSelectOption(base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForHighlightElement( void OnFindElementForHighlightElement(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
...@@ -317,6 +326,7 @@ class WebController { ...@@ -317,6 +326,7 @@ class WebController {
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnHighlightElement( void OnHighlightElement(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForGetFieldValue( void OnFindElementForGetFieldValue(
base::OnceCallback<void(bool, const std::string&)> callback, base::OnceCallback<void(bool, const std::string&)> callback,
...@@ -324,6 +334,7 @@ class WebController { ...@@ -324,6 +334,7 @@ class WebController {
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnGetValueAttribute( void OnGetValueAttribute(
base::OnceCallback<void(bool, const std::string&)> callback, base::OnceCallback<void(bool, const std::string&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void InternalSetFieldValue( void InternalSetFieldValue(
const Selector& selector, const Selector& selector,
...@@ -358,6 +369,7 @@ class WebController { ...@@ -358,6 +369,7 @@ class WebController {
const ClientStatus& status, const ClientStatus& status,
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnSetAttribute(base::OnceCallback<void(const ClientStatus&)> callback, void OnSetAttribute(base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForSendKeyboardInput( void OnFindElementForSendKeyboardInput(
const Selector& selector, const Selector& selector,
...@@ -373,6 +385,7 @@ class WebController { ...@@ -373,6 +385,7 @@ class WebController {
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnSetValueAttribute( void OnSetValueAttribute(
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForGetOuterHtml( void OnFindElementForGetOuterHtml(
base::OnceCallback<void(const ClientStatus&, const std::string&)> base::OnceCallback<void(const ClientStatus&, const std::string&)>
...@@ -381,6 +394,7 @@ class WebController { ...@@ -381,6 +394,7 @@ class WebController {
std::unique_ptr<ElementFinder::Result> element_result); std::unique_ptr<ElementFinder::Result> element_result);
void OnGetOuterHtml(base::OnceCallback<void(const ClientStatus&, void OnGetOuterHtml(base::OnceCallback<void(const ClientStatus&,
const std::string&)> callback, const std::string&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForPosition( void OnFindElementForPosition(
base::OnceCallback<void(bool, const RectF&)> callback, base::OnceCallback<void(bool, const RectF&)> callback,
...@@ -388,9 +402,11 @@ class WebController { ...@@ -388,9 +402,11 @@ class WebController {
std::unique_ptr<ElementFinder::Result> result); std::unique_ptr<ElementFinder::Result> result);
void OnGetVisualViewport( void OnGetVisualViewport(
base::OnceCallback<void(bool, const RectF&)> callback, base::OnceCallback<void(bool, const RectF&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::EvaluateResult> result); std::unique_ptr<runtime::EvaluateResult> result);
void OnGetElementPositionResult( void OnGetElementPositionResult(
base::OnceCallback<void(bool, const RectF&)> callback, base::OnceCallback<void(bool, const RectF&)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
// Creates a new instance of DispatchKeyEventParams for the specified type and // Creates a new instance of DispatchKeyEventParams for the specified type and
...@@ -410,6 +426,7 @@ class WebController { ...@@ -410,6 +426,7 @@ class WebController {
int remaining_rounds, int remaining_rounds,
std::string object_id, std::string object_id,
base::OnceCallback<void(bool)> callback, base::OnceCallback<void(bool)> callback,
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result); std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnFindElementForWaitForDocumentReadyState( void OnFindElementForWaitForDocumentReadyState(
DocumentReadyState min_ready_state, DocumentReadyState min_ready_state,
......
...@@ -14,14 +14,28 @@ ClientStatus UnexpectedErrorStatus(const std::string& file, int line) { ...@@ -14,14 +14,28 @@ ClientStatus UnexpectedErrorStatus(const std::string& file, int line) {
return status; return status;
} }
ClientStatus JavaScriptErrorStatus(const std::string& file, ClientStatus UnexpectedDevtoolsErrorStatus(
const DevtoolsClient::ReplyStatus& reply_status,
const std::string& file,
int line) {
ClientStatus status = UnexpectedErrorStatus(file, line);
if (!reply_status.is_ok()) {
auto* info = status.mutable_details()->mutable_unexpected_error_info();
info->set_devtools_error_code(reply_status.error_code);
info->set_devtools_error_message(reply_status.error_message);
}
return status;
}
ClientStatus JavaScriptErrorStatus(
const DevtoolsClient::ReplyStatus& reply_status,
const std::string& file,
int line, int line,
const runtime::ExceptionDetails* exception) { const runtime::ExceptionDetails* exception) {
ClientStatus status(UNEXPECTED_JS_ERROR); ClientStatus status = UnexpectedDevtoolsErrorStatus(reply_status, file, line);
auto* info = status.mutable_details()->mutable_unexpected_error_info(); status.set_proto_status(UNEXPECTED_JS_ERROR);
info->set_source_file(file);
info->set_source_line_number(line);
if (exception) { if (exception) {
auto* info = status.mutable_details()->mutable_unexpected_error_info();
if (exception->HasException() && if (exception->HasException() &&
exception->GetException()->HasClassName()) { exception->GetException()->HasClassName()) {
info->set_js_exception_classname( info->set_js_exception_classname(
......
...@@ -8,30 +8,48 @@ ...@@ -8,30 +8,48 @@
#include <string> #include <string>
#include "components/autofill_assistant/browser/client_status.h" #include "components/autofill_assistant/browser/client_status.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h"
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
namespace autofill_assistant { namespace autofill_assistant {
// Builds a ClientStatus appropriate for an unexpected error. // Builds a ClientStatus appropriate for an unexpected error.
// //
// This should only be used in situations where getting an error cannot be // This should only be used in situations where getting an error cannot be
// anything but a bug in the client. // anything but a bug in the client and no devtools ReplyStatus is available.
ClientStatus UnexpectedErrorStatus(const std::string& file, int line); ClientStatus UnexpectedErrorStatus(const std::string& file, int line);
// Builds a ClientStatus appropriate for an unexpected error in a devtools
// response.
//
// This should only be used in situations where getting an error cannot be
// anything but a bug in the client.
ClientStatus UnexpectedDevtoolsErrorStatus(
const DevtoolsClient::ReplyStatus& reply_status,
const std::string& file,
int line);
// Builds a ClientStatus appropriate for a JavaScript error. // Builds a ClientStatus appropriate for a JavaScript error.
ClientStatus JavaScriptErrorStatus(const std::string& file, ClientStatus JavaScriptErrorStatus(
const DevtoolsClient::ReplyStatus& reply_status,
const std::string& file,
int line, int line,
const runtime::ExceptionDetails* exception); const runtime::ExceptionDetails* exception);
// Makes sure that the given EvaluateResult exists, is successful and contains a // Makes sure that the given EvaluateResult exists, is successful and contains a
// result. // result.
template <typename T> template <typename T>
ClientStatus CheckJavaScriptResult(T* result, const char* file, int line) { ClientStatus CheckJavaScriptResult(
const DevtoolsClient::ReplyStatus& reply_status,
T* result,
const char* file,
int line) {
if (!result) if (!result)
return JavaScriptErrorStatus(file, line, nullptr); return JavaScriptErrorStatus(reply_status, file, line, nullptr);
if (result->HasExceptionDetails()) if (result->HasExceptionDetails())
return JavaScriptErrorStatus(file, line, result->GetExceptionDetails()); return JavaScriptErrorStatus(reply_status, file, line,
result->GetExceptionDetails());
if (!result->GetResult()) if (!result->GetResult())
return JavaScriptErrorStatus(file, line, nullptr); return JavaScriptErrorStatus(reply_status, file, line, nullptr);
return OkClientStatus(); return OkClientStatus();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment