Web Inspector: there should only be one way for async backend commands to send failure
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Mar 2018 00:43:03 +0000 (00:43 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Mar 2018 00:43:03 +0000 (00:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183524

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

If this is an async command, errors should be reported with BackendDispatcher::CallbackBase::sendFailure.
To avoid mixups, don't include the ErrorString out-parameter in generated async command signatures.
This change only affects interfaces generated for C++ backend dispatchers.

* inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
(CppBackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
* inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
(CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
* inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result:

Source/WebCore:

Remove some useless ErrorString arguments. Fix some bugs where we
may never call the callback in an early exit situation.

Covered by existing Inspector and protocol generator tests.

* inspector/agents/InspectorDatabaseAgent.cpp:
(WebCore::InspectorDatabaseAgent::executeSQL):
* inspector/agents/InspectorDatabaseAgent.h:
* inspector/agents/InspectorIndexedDBAgent.h:
* inspector/agents/InspectorIndexedDBAgent.cpp:
(WebCore::getDocumentAndIDBFactoryFromFrameOrSendFailure):
(WebCore::InspectorIndexedDBAgent::requestDatabaseNames):
(WebCore::InspectorIndexedDBAgent::requestDatabase):
(WebCore::InspectorIndexedDBAgent::requestData):
(WebCore::InspectorIndexedDBAgent::clearObjectStore):
(WebCore::assertDocument): Deleted.
(WebCore::assertIDBFactory): Deleted.
Modernize this code a little bit to share the document/idbFactory extraction code.

* inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::loadResource):
* inspector/agents/InspectorNetworkAgent.h:

Source/WebKit:

Remove useless ErrorString argument from async commands.

For Automation protocol, introduce sync and async macros for filling
in and sending a failure response. Now that async commands don't have
an ErrorString and sync commands don't have a callback, trying to send
an error with the wrong macro is a compile-time error.

* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::getBrowsingContexts):
(WebKit::WebAutomationSession::getBrowsingContext):
(WebKit::WebAutomationSession::createBrowsingContext):
(WebKit::WebAutomationSession::closeBrowsingContext):
(WebKit::WebAutomationSession::switchToBrowsingContext):
(WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext):
(WebKit::WebAutomationSession::waitForNavigationToComplete):
(WebKit::WebAutomationSession::navigateBrowsingContext):
(WebKit::WebAutomationSession::goBackInBrowsingContext):
(WebKit::WebAutomationSession::goForwardInBrowsingContext):
(WebKit::WebAutomationSession::reloadBrowsingContext):
(WebKit::WebAutomationSession::evaluateJavaScriptFunction):
(WebKit::WebAutomationSession::resolveChildFrameHandle):
(WebKit::WebAutomationSession::resolveParentFrameHandle):
(WebKit::WebAutomationSession::computeElementLayout):
(WebKit::WebAutomationSession::selectOptionElement):
(WebKit::WebAutomationSession::isShowingJavaScriptDialog):
(WebKit::WebAutomationSession::dismissCurrentJavaScriptDialog):
(WebKit::WebAutomationSession::acceptCurrentJavaScriptDialog):
(WebKit::WebAutomationSession::messageOfCurrentJavaScriptDialog):
(WebKit::WebAutomationSession::setUserInputForCurrentJavaScriptPrompt):
(WebKit::WebAutomationSession::setFilesToSelectForFileUpload):
(WebKit::WebAutomationSession::getAllCookies):
(WebKit::WebAutomationSession::deleteSingleCookie):
(WebKit::WebAutomationSession::addSingleCookie):
(WebKit::WebAutomationSession::deleteAllCookies):
(WebKit::WebAutomationSession::setSessionPermissions):
(WebKit::WebAutomationSession::performMouseInteraction):
(WebKit::WebAutomationSession::performKeyboardInteractions):
(WebKit::WebAutomationSession::takeScreenshot):
(WebKit::WebAutomationSession::didTakeScreenshot):
* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/Automation/WebAutomationSessionMacros.h:
* UIProcess/Automation/mac/WebAutomationSessionMac.mm:
(WebKit::WebAutomationSession::inspectBrowsingContext):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229493 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py
Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result
Source/WebCore/ChangeLog
Source/WebCore/inspector/agents/InspectorDatabaseAgent.cpp
Source/WebCore/inspector/agents/InspectorDatabaseAgent.h
Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp
Source/WebCore/inspector/agents/InspectorIndexedDBAgent.h
Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
Source/WebCore/inspector/agents/InspectorNetworkAgent.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
Source/WebKit/UIProcess/Automation/WebAutomationSession.h
Source/WebKit/UIProcess/Automation/WebAutomationSessionMacros.h
Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm

index e4e7f33..cb77aa1 100644 (file)
@@ -1,3 +1,20 @@
+2018-03-09  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: there should only be one way for async backend commands to send failure
+        https://bugs.webkit.org/show_bug.cgi?id=183524
+
+        Reviewed by Timothy Hatcher.
+
+        If this is an async command, errors should be reported with BackendDispatcher::CallbackBase::sendFailure.
+        To avoid mixups, don't include the ErrorString out-parameter in generated async command signatures.
+        This change only affects interfaces generated for C++ backend dispatchers.
+
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
+        (CppBackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result:
+
 2018-03-09  Mark Lam  <mark.lam@apple.com>
 
         Build fix after r229476.
index 07dc86d..0769c8a 100755 (executable)
@@ -160,7 +160,7 @@ class CppBackendDispatcherHeaderGenerator(CppGenerator):
     def _generate_async_handler_declaration_for_command(self, command):
         callbackName = "%sCallback" % ucfirst(command.command_name)
 
-        in_parameters = ['ErrorString&']
+        in_parameters = []
         for _parameter in command.call_parameters:
             parameter_name = 'in_' + _parameter.parameter_name
             if _parameter.is_optional:
index be6f45a..aaca392 100755 (executable)
@@ -186,7 +186,9 @@ class CppBackendDispatcherImplementationGenerator(CppGenerator):
         out_parameter_declarations = []
         out_parameter_assignments = []
         alternate_dispatcher_method_parameters = ['requestId']
-        method_parameters = ['error']
+        method_parameters = []
+        if not command.is_async:
+            method_parameters.append('error')
 
         for parameter in command.call_parameters:
             parameter_name = 'in_' + parameter.parameter_name
@@ -299,31 +301,31 @@ class CppBackendDispatcherImplementationGenerator(CppGenerator):
             lines.append('#endif')
             lines.append('')
 
-        lines.append('    ErrorString error;')
-        lines.append('    Ref<JSON::Object> result = JSON::Object::create();')
         if command.is_async:
             lines.append('    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), requestId));' % command_args)
+        else:
+            lines.append('    ErrorString error;')
+            lines.append('    Ref<JSON::Object> result = JSON::Object::create();')
+
         if len(command.return_parameters) > 0:
             lines.extend(out_parameter_declarations)
         lines.append('    m_agent->%(commandName)s(%(invocationParameters)s);' % command_args)
         lines.append('')
-        if command.is_async:
-            lines.append('    if (error.length()) {')
-            lines.extend(out_parameter_assignments)
-            lines.append('    }')
-        elif len(command.return_parameters) > 1:
-            lines.append('    if (!error.length()) {')
-            lines.extend(out_parameter_assignments)
-            lines.append('    }')
-        elif len(command.return_parameters) == 1:
-            lines.append('    if (!error.length())')
-            lines.extend(out_parameter_assignments)
-            lines.append('')
 
         if not command.is_async:
+            if len(command.return_parameters) > 1:
+                lines.append('    if (!error.length()) {')
+                lines.extend(out_parameter_assignments)
+                lines.append('    }')
+            elif len(command.return_parameters) == 1:
+                lines.append('    if (!error.length())')
+                lines.extend(out_parameter_assignments)
+                lines.append('')
+
             lines.append('    if (!error.length())')
             lines.append('        m_backendDispatcher->sendResponse(requestId, WTFMove(result), false);')
             lines.append('    else')
             lines.append('        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));')
+
         lines.append('}')
         return "\n".join(lines)
index 40f3908..824b606 100644 (file)
@@ -163,14 +163,14 @@ public:
         ExecuteSQLAsyncOptionalReturnValuesCallback(Ref<BackendDispatcher>&&, int id);
         void sendSuccess(RefPtr<JSON::ArrayOf<String>>&& columnNames, std::optional<String>& notes, std::optional<double>& timestamp, std::optional<JSON::Object>& values, std::optional<JSON::Value>& payload, std::optional<int>& databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, std::optional<String>& screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, std::optional<String>& printColor);
     };
-    virtual void executeSQLAsyncOptionalReturnValues(ErrorString&, int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncOptionalReturnValuesCallback>&& callback) = 0;
+    virtual void executeSQLAsyncOptionalReturnValues(int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncOptionalReturnValuesCallback>&& callback) = 0;
     virtual void executeSQLSync(ErrorString&, int in_databaseId, const String& in_query, RefPtr<JSON::ArrayOf<String>>& out_columnNames, String* out_notes, double* out_timestamp, JSON::Object* out_values, JSON::Value* out_payload, int* out_databaseId, RefPtr<Inspector::Protocol::Database::Error>& out_sqlError, RefPtr<Inspector::Protocol::Database::ColorList>& out_alternateColors, Inspector::Protocol::Database::PrimaryColors* out_screenColor, DatabaseBackendDispatcherHandler::PrintColor* out_printColor) = 0;
     class ExecuteSQLAsyncCallback : public BackendDispatcher::CallbackBase {
     public:
         ExecuteSQLAsyncCallback(Ref<BackendDispatcher>&&, int id);
         void sendSuccess(RefPtr<JSON::ArrayOf<String>>&& columnNames, const String& notes, double timestamp, JSON::Object values, JSON::Value payload, int databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, const String& screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, const String& printColor);
     };
-    virtual void executeSQLAsync(ErrorString&, int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncCallback>&& callback) = 0;
+    virtual void executeSQLAsync(int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncCallback>&& callback) = 0;
 protected:
     virtual ~DatabaseBackendDispatcherHandler();
 };
@@ -378,16 +378,9 @@ void DatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long request
     }
 #endif
 
-    ErrorString error;
-    Ref<JSON::Object> result = JSON::Object::create();
     Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback(m_backendDispatcher.copyRef(), requestId));
-    m_agent->executeSQLAsyncOptionalReturnValues(error, in_databaseId, in_query, callback.copyRef());
+    m_agent->executeSQLAsyncOptionalReturnValues(in_databaseId, in_query, callback.copyRef());
 
-    if (error.length()) {
-        callback->disable();
-        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
-        return;
-    }
 }
 
 void DatabaseBackendDispatcher::executeSQLSync(long requestId, RefPtr<JSON::Object>&& parameters)
@@ -472,16 +465,9 @@ void DatabaseBackendDispatcher::executeSQLAsync(long requestId, RefPtr<JSON::Obj
     }
 #endif
 
-    ErrorString error;
-    Ref<JSON::Object> result = JSON::Object::create();
     Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback(m_backendDispatcher.copyRef(), requestId));
-    m_agent->executeSQLAsync(error, in_databaseId, in_query, callback.copyRef());
+    m_agent->executeSQLAsync(in_databaseId, in_query, callback.copyRef());
 
-    if (error.length()) {
-        callback->disable();
-        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
-        return;
-    }
 }
 
 } // namespace Inspector
index bef9e6e..076f564 100644 (file)
@@ -1,3 +1,33 @@
+2018-03-09  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: there should only be one way for async backend commands to send failure
+        https://bugs.webkit.org/show_bug.cgi?id=183524
+
+        Reviewed by Timothy Hatcher.
+
+        Remove some useless ErrorString arguments. Fix some bugs where we
+        may never call the callback in an early exit situation.
+
+        Covered by existing Inspector and protocol generator tests.
+
+        * inspector/agents/InspectorDatabaseAgent.cpp:
+        (WebCore::InspectorDatabaseAgent::executeSQL):
+        * inspector/agents/InspectorDatabaseAgent.h:
+        * inspector/agents/InspectorIndexedDBAgent.h:
+        * inspector/agents/InspectorIndexedDBAgent.cpp:
+        (WebCore::getDocumentAndIDBFactoryFromFrameOrSendFailure):
+        (WebCore::InspectorIndexedDBAgent::requestDatabaseNames):
+        (WebCore::InspectorIndexedDBAgent::requestDatabase):
+        (WebCore::InspectorIndexedDBAgent::requestData):
+        (WebCore::InspectorIndexedDBAgent::clearObjectStore):
+        (WebCore::assertDocument): Deleted.
+        (WebCore::assertIDBFactory): Deleted.
+        Modernize this code a little bit to share the document/idbFactory extraction code.
+
+        * inspector/agents/InspectorNetworkAgent.cpp:
+        (WebCore::InspectorNetworkAgent::loadResource):
+        * inspector/agents/InspectorNetworkAgent.h:
+
 2018-03-09  Youenn Fablet  <youenn@apple.com>
 
         Crash in ServiceWorkerContainer::ready
index eede399..70ddfc1 100644 (file)
@@ -271,7 +271,7 @@ void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString& error, const Str
     }
 }
 
-void InspectorDatabaseAgent::executeSQL(ErrorString&, const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&& requestCallback)
+void InspectorDatabaseAgent::executeSQL(const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&& requestCallback)
 {
     if (!m_enabled) {
         requestCallback->sendFailure("Database agent is not enabled");
index 6ca8159..a0aaade 100644 (file)
@@ -58,7 +58,7 @@ public:
     void enable(ErrorString&) override;
     void disable(ErrorString&) override;
     void getDatabaseTableNames(ErrorString&, const String& databaseId, RefPtr<JSON::ArrayOf<String>>& names) override;
-    void executeSQL(ErrorString&, const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&&) override;
+    void executeSQL(const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&&) override;
 
     // Called from the injected script.
     String databaseId(Database&);
index 4d4bb23..f74f941 100644 (file)
@@ -84,6 +84,10 @@ typedef Inspector::IndexedDBBackendDispatcherHandler::RequestDatabaseCallback Re
 typedef Inspector::IndexedDBBackendDispatcherHandler::RequestDataCallback RequestDataCallback;
 typedef Inspector::IndexedDBBackendDispatcherHandler::ClearObjectStoreCallback ClearObjectStoreCallback;
 
+typedef String ErrorString;
+
+template <typename T>
+using ErrorStringOr = Expected<T, ErrorString>;
 
 namespace WebCore {
 
@@ -538,45 +542,58 @@ void InspectorIndexedDBAgent::disable(ErrorString&)
 {
 }
 
-static Document* assertDocument(ErrorString& errorString, Frame* frame)
+static ErrorStringOr<Document*> documentFromFrame(Frame* frame)
 {
     Document* document = frame ? frame->document() : nullptr;
     if (!document)
-        errorString = ASCIILiteral("No document for given frame found");
+        return makeUnexpected(ASCIILiteral("No document for given frame found"));
+    
     return document;
 }
 
-static IDBFactory* assertIDBFactory(ErrorString& errorString, Document* document)
+static ErrorStringOr<IDBFactory*> IDBFactoryFromDocument(Document* document)
 {
     DOMWindow* domWindow = document->domWindow();
-    if (!domWindow) {
-        errorString = ASCIILiteral("No IndexedDB factory for given frame found");
-        return nullptr;
-    }
+    if (!domWindow)
+        return makeUnexpected(ASCIILiteral("No IndexedDB factory for given frame found"));
 
     IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(*domWindow);
     if (!idbFactory)
-        errorString = ASCIILiteral("No IndexedDB factory for given frame found");
-
+        makeUnexpected(ASCIILiteral("No IndexedDB factory for given frame found"));
+    
     return idbFactory;
 }
 
-void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString& errorString, const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&& requestCallback)
+static bool getDocumentAndIDBFactoryFromFrameOrSendFailure(Frame* frame, Document*& out_document, IDBFactory*& out_idbFactory, BackendDispatcher::CallbackBase& callback)
+{
+    ErrorStringOr<Document*> document = documentFromFrame(frame);
+    if (!document.has_value()) {
+        callback.sendFailure(document.error());
+        return false;
+    }
+
+    ErrorStringOr<IDBFactory*> idbFactory = IDBFactoryFromDocument(document.value());
+    if (!idbFactory.has_value()) {
+        callback.sendFailure(idbFactory.error());
+        return false;
+    }
+    
+    out_document = document.value();
+    out_idbFactory = idbFactory.value();
+    return true;
+}
+    
+void InspectorIndexedDBAgent::requestDatabaseNames(const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&& callback)
 {
     Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
-    Document* document = assertDocument(errorString, frame);
-    if (!document)
+    Document* document;
+    IDBFactory* idbFactory;
+    if (!getDocumentAndIDBFactoryFromFrameOrSendFailure(frame, document, idbFactory, callback))
         return;
 
     auto& openingOrigin = document->securityOrigin();
-
     auto& topOrigin = document->topOrigin();
-
-    IDBFactory* idbFactory = assertIDBFactory(errorString, document);
-    if (!idbFactory)
-        return;
-
-    idbFactory->getAllDatabaseNames(topOrigin, openingOrigin, [callback = WTFMove(requestCallback)](auto& databaseNames) {
+    idbFactory->getAllDatabaseNames(topOrigin, openingOrigin, [callback = WTFMove(callback)](auto& databaseNames) {
         if (!callback->isActive())
             return;
 
@@ -588,41 +605,34 @@ void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString& errorString, con
     });
 }
 
-void InspectorIndexedDBAgent::requestDatabase(ErrorString& errorString, const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&& requestCallback)
+void InspectorIndexedDBAgent::requestDatabase(const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&& callback)
 {
     Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
-    Document* document = assertDocument(errorString, frame);
-    if (!document)
+    Document* document;
+    IDBFactory* idbFactory;
+    if (!getDocumentAndIDBFactoryFromFrameOrSendFailure(frame, document, idbFactory, callback))
         return;
 
-    IDBFactory* idbFactory = assertIDBFactory(errorString, document);
-    if (!idbFactory)
-        return;
-
-    Ref<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, WTFMove(requestCallback));
+    Ref<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, WTFMove(callback));
     databaseLoader->start(idbFactory, &document->securityOrigin(), databaseName);
 }
 
-void InspectorIndexedDBAgent::requestData(ErrorString& errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const JSON::Object* keyRange, Ref<RequestDataCallback>&& requestCallback)
+void InspectorIndexedDBAgent::requestData(const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const JSON::Object* keyRange, Ref<RequestDataCallback>&& callback)
 {
     Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
-    Document* document = assertDocument(errorString, frame);
-    if (!document)
-        return;
-
-    IDBFactory* idbFactory = assertIDBFactory(errorString, document);
-    if (!idbFactory)
+    Document* document;
+    IDBFactory* idbFactory;
+    if (!getDocumentAndIDBFactoryFromFrameOrSendFailure(frame, document, idbFactory, callback))
         return;
 
     InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(mainWorldExecState(frame));
-
     RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRange) : nullptr;
     if (keyRange && !idbKeyRange) {
-        errorString = ASCIILiteral("Can not parse key range.");
+        callback->sendFailure(ASCIILiteral("Can not parse key range."));
         return;
     }
 
-    Ref<DataLoader> dataLoader = DataLoader::create(document, WTFMove(requestCallback), injectedScript, objectStoreName, indexName, WTFMove(idbKeyRange), skipCount, pageSize);
+    Ref<DataLoader> dataLoader = DataLoader::create(document, WTFMove(callback), injectedScript, objectStoreName, indexName, WTFMove(idbKeyRange), skipCount, pageSize);
     dataLoader->start(idbFactory, &document->securityOrigin(), databaseName);
 }
 
@@ -718,17 +728,15 @@ private:
 
 } // anonymous namespace
 
-void InspectorIndexedDBAgent::clearObjectStore(ErrorString& errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& requestCallback)
+void InspectorIndexedDBAgent::clearObjectStore(const String& securityOrigin, const String& databaseName, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& callback)
 {
     Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
-    Document* document = assertDocument(errorString, frame);
-    if (!document)
-        return;
-    IDBFactory* idbFactory = assertIDBFactory(errorString, document);
-    if (!idbFactory)
+    Document* document;
+    IDBFactory* idbFactory;
+    if (!getDocumentAndIDBFactoryFromFrameOrSendFailure(frame, document, idbFactory, callback))
         return;
 
-    Ref<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, WTFMove(requestCallback));
+    Ref<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, WTFMove(callback));
     clearObjectStore->start(idbFactory, &document->securityOrigin(), databaseName);
 }
 
index 08b1aff..4f6f2e9 100644 (file)
@@ -60,10 +60,10 @@ public:
     // Called from the front-end.
     void enable(ErrorString&) override;
     void disable(ErrorString&) override;
-    void requestDatabaseNames(ErrorString&, const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&&) override;
-    void requestDatabase(ErrorString&, const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&&) override;
-    void requestData(ErrorString&, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const JSON::Object* keyRange, Ref<RequestDataCallback>&&) override;
-    void clearObjectStore(ErrorString&, const String& in_securityOrigin, const String& in_databaseName, const String& in_objectStoreName, Ref<ClearObjectStoreCallback>&&) override;
+    void requestDatabaseNames(const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&&) override;
+    void requestDatabase(const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&&) override;
+    void requestData(const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const JSON::Object* keyRange, Ref<RequestDataCallback>&&) override;
+    void clearObjectStore(const String& in_securityOrigin, const String& in_databaseName, const String& in_objectStoreName, Ref<ClearObjectStoreCallback>&&) override;
 
 private:
     Inspector::InjectedScriptManager& m_injectedScriptManager;
index 4d0958a..6b93dab 100644 (file)
@@ -787,11 +787,14 @@ void InspectorNetworkAgent::setResourceCachingDisabled(ErrorString&, bool disabl
     setResourceCachingDisabled(disabled);
 }
 
-void InspectorNetworkAgent::loadResource(ErrorString& errorString, const String& frameId, const String& urlString, Ref<LoadResourceCallback>&& callback)
+void InspectorNetworkAgent::loadResource(const String& frameId, const String& urlString, Ref<LoadResourceCallback>&& callback)
 {
-    auto* context = scriptExecutionContext(errorString, frameId);
-    if (!context)
+    ErrorString error;
+    auto* context = scriptExecutionContext(error, frameId);
+    if (!context) {
+        callback->sendFailure(error);
         return;
+    }
 
     URL url = context->completeURL(urlString);
     ResourceRequest request(url);
@@ -808,8 +811,10 @@ void InspectorNetworkAgent::loadResource(ErrorString& errorString, const String&
     // InspectorThreadableLoaderClient deletes itself when the load completes or fails.
     InspectorThreadableLoaderClient* inspectorThreadableLoaderClient = new InspectorThreadableLoaderClient(callback.copyRef());
     auto loader = ThreadableLoader::create(*context, *inspectorThreadableLoaderClient, WTFMove(request), options);
-    if (!loader)
+    if (!loader) {
+        callback->sendFailure(ASCIILiteral("Could not load requested resource."));
         return;
+    }
 
     // If the load already completed, inspectorThreadableLoaderClient will have been deleted and we will have already called the callback.
     if (!callback->isActive())
index 411f174..64d0e04 100644 (file)
@@ -115,7 +115,7 @@ public:
     void setExtraHTTPHeaders(ErrorString&, const JSON::Object& headers) final;
     void getResponseBody(ErrorString&, const String& requestId, String* content, bool* base64Encoded) final;
     void setResourceCachingDisabled(ErrorString&, bool disabled) final;
-    void loadResource(ErrorString&, const String& frameId, const String& url, Ref<LoadResourceCallback>&&) final;
+    void loadResource(const String& frameId, const String& url, Ref<LoadResourceCallback>&&) final;
     void resolveWebSocket(ErrorString&, const String& requestId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) final;
 
     virtual String loaderIdentifier(DocumentLoader*) = 0;
index 2b3ef29..54a94f6 100644 (file)
@@ -1,3 +1,54 @@
+2018-03-09  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: there should only be one way for async backend commands to send failure
+        https://bugs.webkit.org/show_bug.cgi?id=183524
+
+        Reviewed by Timothy Hatcher.
+
+        Remove useless ErrorString argument from async commands.
+
+        For Automation protocol, introduce sync and async macros for filling
+        in and sending a failure response. Now that async commands don't have
+        an ErrorString and sync commands don't have a callback, trying to send
+        an error with the wrong macro is a compile-time error.
+
+        * UIProcess/Automation/WebAutomationSession.cpp:
+        (WebKit::WebAutomationSession::getBrowsingContexts):
+        (WebKit::WebAutomationSession::getBrowsingContext):
+        (WebKit::WebAutomationSession::createBrowsingContext):
+        (WebKit::WebAutomationSession::closeBrowsingContext):
+        (WebKit::WebAutomationSession::switchToBrowsingContext):
+        (WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext):
+        (WebKit::WebAutomationSession::waitForNavigationToComplete):
+        (WebKit::WebAutomationSession::navigateBrowsingContext):
+        (WebKit::WebAutomationSession::goBackInBrowsingContext):
+        (WebKit::WebAutomationSession::goForwardInBrowsingContext):
+        (WebKit::WebAutomationSession::reloadBrowsingContext):
+        (WebKit::WebAutomationSession::evaluateJavaScriptFunction):
+        (WebKit::WebAutomationSession::resolveChildFrameHandle):
+        (WebKit::WebAutomationSession::resolveParentFrameHandle):
+        (WebKit::WebAutomationSession::computeElementLayout):
+        (WebKit::WebAutomationSession::selectOptionElement):
+        (WebKit::WebAutomationSession::isShowingJavaScriptDialog):
+        (WebKit::WebAutomationSession::dismissCurrentJavaScriptDialog):
+        (WebKit::WebAutomationSession::acceptCurrentJavaScriptDialog):
+        (WebKit::WebAutomationSession::messageOfCurrentJavaScriptDialog):
+        (WebKit::WebAutomationSession::setUserInputForCurrentJavaScriptPrompt):
+        (WebKit::WebAutomationSession::setFilesToSelectForFileUpload):
+        (WebKit::WebAutomationSession::getAllCookies):
+        (WebKit::WebAutomationSession::deleteSingleCookie):
+        (WebKit::WebAutomationSession::addSingleCookie):
+        (WebKit::WebAutomationSession::deleteAllCookies):
+        (WebKit::WebAutomationSession::setSessionPermissions):
+        (WebKit::WebAutomationSession::performMouseInteraction):
+        (WebKit::WebAutomationSession::performKeyboardInteractions):
+        (WebKit::WebAutomationSession::takeScreenshot):
+        (WebKit::WebAutomationSession::didTakeScreenshot):
+        * UIProcess/Automation/WebAutomationSession.h:
+        * UIProcess/Automation/WebAutomationSessionMacros.h:
+        * UIProcess/Automation/mac/WebAutomationSessionMac.mm:
+        (WebKit::WebAutomationSession::inspectBrowsingContext):
+
 2018-03-09  Jer Noble  <jer.noble@apple.com>
 
         Don't pass NULL to the result parameter of SecTrustEvaluate()
index 29685bf..d2a939e 100644 (file)
@@ -245,7 +245,7 @@ void WebAutomationSession::getNextContext(Ref<WebAutomationSession>&& protectedT
     });
 }
     
-void WebAutomationSession::getBrowsingContexts(Inspector::ErrorString& errorString, Ref<GetBrowsingContextsCallback>&& callback)
+void WebAutomationSession::getBrowsingContexts(Ref<GetBrowsingContextsCallback>&& callback)
 {
     Vector<Ref<WebPageProxy>> pages;
     for (auto& process : m_processPool->processes()) {
@@ -260,11 +260,11 @@ void WebAutomationSession::getBrowsingContexts(Inspector::ErrorString& errorStri
     getNextContext(makeRef(*this), WTFMove(pages), JSON::ArrayOf<Inspector::Protocol::Automation::BrowsingContext>::create(), WTFMove(callback));
 }
 
-void WebAutomationSession::getBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<GetBrowsingContextCallback>&& callback)
+void WebAutomationSession::getBrowsingContext(const String& handle, Ref<GetBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     page->getWindowFrameWithCallback([protectedThis = makeRef(*this), page = makeRef(*page), callback = WTFMove(callback)](WebCore::FloatRect windowFrame) mutable {
         callback->sendSuccess(protectedThis->buildBrowsingContextForPage(page.get(), windowFrame));
@@ -275,11 +275,11 @@ void WebAutomationSession::createBrowsingContext(Inspector::ErrorString& errorSt
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session could not request a new browsing context.");
+        SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session could not request a new browsing context.");
 
     WebPageProxy* page = m_client->didRequestNewWindow(*this);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session failed to create a new browsing context.");
+        SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session failed to create a new browsing context.");
 
     m_activeBrowsingContextHandle = *handle = handleForWebPageProxy(*page);
 }
@@ -288,7 +288,7 @@ void WebAutomationSession::closeBrowsingContext(Inspector::ErrorString& errorStr
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (handle == m_activeBrowsingContextHandle)
         m_activeBrowsingContextHandle = emptyString();
@@ -300,11 +300,11 @@ void WebAutomationSession::switchToBrowsingContext(Inspector::ErrorString& error
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString());
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     // FIXME: We don't need to track this in WK2. Remove in a follow up.
     m_activeBrowsingContextHandle = browsingContextHandle;
@@ -313,46 +313,46 @@ void WebAutomationSession::switchToBrowsingContext(Inspector::ErrorString& error
     page->process().send(Messages::WebAutomationSessionProxy::FocusFrame(page->pageID(), frameID.value()), 0);
 }
 
-void WebAutomationSession::setWindowFrameOfBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const JSON::Object* optionalOriginObject, const JSON::Object* optionalSizeObject, Ref<SetWindowFrameOfBrowsingContextCallback>&& callback)
+void WebAutomationSession::setWindowFrameOfBrowsingContext(const String& handle, const JSON::Object* optionalOriginObject, const JSON::Object* optionalSizeObject, Ref<SetWindowFrameOfBrowsingContextCallback>&& callback)
 {
 #if PLATFORM(IOS)
-    FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
+    ASYNC_FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
 #else
     std::optional<float> x;
     std::optional<float> y;
     if (optionalOriginObject) {
         if (!(x = optionalOriginObject->getNumber<float>(WTF::ASCIILiteral("x"))))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'x' parameter was not found or invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'x' parameter was not found or invalid.");
 
         if (!(y = optionalOriginObject->getNumber<float>(WTF::ASCIILiteral("y"))))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'y' parameter was not found or invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'y' parameter was not found or invalid.");
 
         if (x.value() < 0)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'x' parameter had an invalid value.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'x' parameter had an invalid value.");
 
         if (y.value() < 0)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'y' parameter had an invalid value.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'y' parameter had an invalid value.");
     }
 
     std::optional<float> width;
     std::optional<float> height;
     if (optionalSizeObject) {
         if (!(width = optionalSizeObject->getNumber<float>(WTF::ASCIILiteral("width"))))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'width' parameter was not found or invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'width' parameter was not found or invalid.");
 
         if (!(height = optionalSizeObject->getNumber<float>(WTF::ASCIILiteral("height"))))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'height' parameter was not found or invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'height' parameter was not found or invalid.");
 
         if (width.value() < 0)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'width' parameter had an invalid value.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'width' parameter had an invalid value.");
 
         if (height.value() < 0)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'height' parameter had an invalid value.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'height' parameter had an invalid value.");
     }
 
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     // FIXME (§10.7.2 Step 10): We need to exit fullscreen before setting the frame.
     // FIXME (§10.7.2 Step 11): We need to de-miniaturize the window before setting the frame.
@@ -379,15 +379,15 @@ static std::optional<Inspector::Protocol::Automation::PageLoadStrategy> pageLoad
     return parsedPageLoadStrategy;
 }
 
-void WebAutomationSession::waitForNavigationToComplete(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<WaitForNavigationToCompleteCallback>&& callback)
+void WebAutomationSession::waitForNavigationToComplete(const String& browsingContextHandle, const String* optionalFrameHandle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<WaitForNavigationToCompleteCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
     if (!pageLoadStrategy)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
     auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     // If page is loading and there's an active JavaScript dialog is probably because the
@@ -401,10 +401,10 @@ void WebAutomationSession::waitForNavigationToComplete(Inspector::ErrorString& e
     if (optionalFrameHandle && !optionalFrameHandle->isEmpty()) {
         std::optional<uint64_t> frameID = webFrameIDForHandle(*optionalFrameHandle);
         if (!frameID)
-            FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
         WebFrameProxy* frame = page->process().webFrame(frameID.value());
         if (!frame)
-            FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
         if (!shouldTimeoutDueToUnexpectedAlert)
             waitForNavigationToCompleteOnFrame(*frame, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
     } else {
@@ -534,60 +534,60 @@ void WebAutomationSession::willShowJavaScriptDialog(WebPageProxy& page)
     });
 }
 
-void WebAutomationSession::navigateBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&& callback)
+void WebAutomationSession::navigateBrowsingContext(const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
     if (!pageLoadStrategy)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
     auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->loadRequest(WebCore::URL(WebCore::URL(), url));
     waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
-void WebAutomationSession::goBackInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&& callback)
+void WebAutomationSession::goBackInBrowsingContext(const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
     if (!pageLoadStrategy)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
     auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->goBack();
     waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
-void WebAutomationSession::goForwardInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoForwardInBrowsingContextCallback>&& callback)
+void WebAutomationSession::goForwardInBrowsingContext(const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoForwardInBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
     if (!pageLoadStrategy)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
     auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->goForward();
     waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
-void WebAutomationSession::reloadBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<ReloadBrowsingContextCallback>&& callback)
+void WebAutomationSession::reloadBrowsingContext(const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<ReloadBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
     if (!pageLoadStrategy)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
     auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->reload({ });
@@ -732,15 +732,15 @@ void WebAutomationSession::handleRunOpenPanel(const WebPageProxy& page, const We
     m_domainNotifier->fileChooserDismissed(m_activeBrowsingContextHandle, false);
 }
 
-void WebAutomationSession::evaluateJavaScriptFunction(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const JSON::Array& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<EvaluateJavaScriptFunctionCallback>&& callback)
+void WebAutomationSession::evaluateJavaScriptFunction(const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const JSON::Array& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<EvaluateJavaScriptFunctionCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString());
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     Vector<String> argumentsVector;
     argumentsVector.reserveCapacity(arguments.length());
@@ -772,18 +772,18 @@ void WebAutomationSession::didEvaluateJavaScriptFunction(uint64_t callbackID, co
         callback->sendSuccess(result);
 }
 
-void WebAutomationSession::resolveChildFrameHandle(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&& callback)
+void WebAutomationSession::resolveChildFrameHandle(const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&& callback)
 {
     if (!optionalOrdinal && !optionalName && !optionalNodeHandle)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "Command must specify a child frame by ordinal, name, or element handle.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "Command must specify a child frame by ordinal, name, or element handle.");
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString());
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     uint64_t callbackID = m_nextResolveFrameCallbackID++;
     m_resolveChildFrameHandleCallbacks.set(callbackID, WTFMove(callback));
@@ -818,15 +818,15 @@ void WebAutomationSession::didResolveChildFrame(uint64_t callbackID, uint64_t fr
         callback->sendSuccess(handleForWebFrameID(frameID));
 }
 
-void WebAutomationSession::resolveParentFrameHandle(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&& callback)
+void WebAutomationSession::resolveParentFrameHandle(const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(frameHandle);
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     uint64_t callbackID = m_nextResolveParentFrameCallbackID++;
     m_resolveParentFrameHandleCallbacks.set(callbackID, WTFMove(callback));
@@ -857,19 +857,19 @@ static std::optional<CoordinateSystem> protocolStringToCoordinateSystem(const St
     return std::nullopt;
 }
 
-void WebAutomationSession::computeElementLayout(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const String& coordinateSystemString, Ref<ComputeElementLayoutCallback>&& callback)
+void WebAutomationSession::computeElementLayout(const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const String& coordinateSystemString, Ref<ComputeElementLayoutCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(frameHandle);
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     std::optional<CoordinateSystem> coordinateSystem = protocolStringToCoordinateSystem(coordinateSystemString);
     if (!coordinateSystem)
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'coordinateSystem' is invalid.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'coordinateSystem' is invalid.");
 
     uint64_t callbackID = m_nextComputeElementLayoutCallbackID++;
     m_computeElementLayoutCallbacks.set(callbackID, WTFMove(callback));
@@ -917,15 +917,15 @@ void WebAutomationSession::didComputeElementLayout(uint64_t callbackID, WebCore:
     callback->sendSuccess(WTFMove(rectObject), WTFMove(inViewCenterPointObject), isObscured);
 }
 
-void WebAutomationSession::selectOptionElement(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, Ref<SelectOptionElementCallback>&& callback)
+void WebAutomationSession::selectOptionElement(const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, Ref<SelectOptionElementCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(frameHandle);
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     uint64_t callbackID = m_nextSelectOptionElementCallbackID++;
     m_selectOptionElementCallbacks.set(callbackID, WTFMove(callback));
@@ -952,11 +952,11 @@ void WebAutomationSession::isShowingJavaScriptDialog(Inspector::ErrorString& err
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR(InternalError);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     *result = m_client->isShowingJavaScriptDialogOnPage(*this, *page);
 }
@@ -965,14 +965,14 @@ void WebAutomationSession::dismissCurrentJavaScriptDialog(Inspector::ErrorString
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR(InternalError);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (!m_client->isShowingJavaScriptDialogOnPage(*this, *page))
-        FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
 
     m_client->dismissCurrentJavaScriptDialogOnPage(*this, *page);
 }
@@ -981,14 +981,14 @@ void WebAutomationSession::acceptCurrentJavaScriptDialog(Inspector::ErrorString&
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR(InternalError);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (!m_client->isShowingJavaScriptDialogOnPage(*this, *page))
-        FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
 
     m_client->acceptCurrentJavaScriptDialogOnPage(*this, *page);
 }
@@ -997,14 +997,14 @@ void WebAutomationSession::messageOfCurrentJavaScriptDialog(Inspector::ErrorStri
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR(InternalError);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (!m_client->isShowingJavaScriptDialogOnPage(*this, *page))
-        FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
 
     *text = m_client->messageOfCurrentJavaScriptDialogOnPage(*this, *page);
 }
@@ -1013,14 +1013,14 @@ void WebAutomationSession::setUserInputForCurrentJavaScriptPrompt(Inspector::Err
 {
     ASSERT(m_client);
     if (!m_client)
-        FAIL_WITH_PREDEFINED_ERROR(InternalError);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (!m_client->isShowingJavaScriptDialogOnPage(*this, *page))
-        FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
 
     // §18.4 Send Alert Text.
     // https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text
@@ -1031,13 +1031,13 @@ void WebAutomationSession::setUserInputForCurrentJavaScriptPrompt(Inspector::Err
     case API::AutomationSessionClient::JavaScriptDialogType::Alert:
     case API::AutomationSessionClient::JavaScriptDialogType::Confirm:
         // Return error with error code element not interactable.
-        FAIL_WITH_PREDEFINED_ERROR(ElementNotInteractable);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(ElementNotInteractable);
     case API::AutomationSessionClient::JavaScriptDialogType::Prompt:
         // Do nothing.
         break;
     case API::AutomationSessionClient::JavaScriptDialogType::BeforeUnloadConfirm:
         // Return error with error code unsupported operation.
-        FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
     }
 
     m_client->setUserInputForCurrentJavaScriptPromptOnPage(*this, *page, promptValue);
@@ -1051,7 +1051,7 @@ void WebAutomationSession::setFilesToSelectForFileUpload(ErrorString& errorStrin
     for (auto item : filenames) {
         String filename;
         if (!item->asString(filename))
-            FAIL_WITH_PREDEFINED_ERROR(InternalError);
+            SYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
         newFileList.append(filename);
     }
@@ -1059,11 +1059,11 @@ void WebAutomationSession::setFilesToSelectForFileUpload(ErrorString& errorStrin
     m_filesToSelectForFileUpload.swap(newFileList);
 }
 
-void WebAutomationSession::getAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&& callback)
+void WebAutomationSession::getAllCookies(const String& browsingContextHandle, Ref<GetAllCookiesCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     // Always send the main frame ID as 0 so it is resolved on the WebProcess side. This avoids a race when page->mainFrame() is null still.
     const uint64_t mainFrameID = 0;
@@ -1113,11 +1113,11 @@ void WebAutomationSession::didGetCookiesForFrame(uint64_t callbackID, Vector<Web
     callback->sendSuccess(buildArrayForCookies(cookies));
 }
 
-void WebAutomationSession::deleteSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&& callback)
+void WebAutomationSession::deleteSingleCookie(const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     // Always send the main frame ID as 0 so it is resolved on the WebProcess side. This avoids a race when page->mainFrame() is null still.
     const uint64_t mainFrameID = 0;
@@ -1142,11 +1142,11 @@ void WebAutomationSession::didDeleteCookie(uint64_t callbackID, const String& er
     callback->sendSuccess();
 }
 
-void WebAutomationSession::addSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const JSON::Object& cookieObject, Ref<AddSingleCookieCallback>&& callback)
+void WebAutomationSession::addSingleCookie(const String& browsingContextHandle, const JSON::Object& cookieObject, Ref<AddSingleCookieCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL());
     ASSERT(activeURL.isValid());
@@ -1154,14 +1154,14 @@ void WebAutomationSession::addSingleCookie(ErrorString& errorString, const Strin
     WebCore::Cookie cookie;
 
     if (!cookieObject.getString(WTF::ASCIILiteral("name"), cookie.name))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'name' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'name' was not found.");
 
     if (!cookieObject.getString(WTF::ASCIILiteral("value"), cookie.value))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'value' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'value' was not found.");
 
     String domain;
     if (!cookieObject.getString(WTF::ASCIILiteral("domain"), domain))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'domain' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'domain' was not found.");
 
     // Inherit the domain/host from the main frame's URL if it is not explicitly set.
     if (domain.isEmpty())
@@ -1175,22 +1175,22 @@ void WebAutomationSession::addSingleCookie(ErrorString& errorString, const Strin
     cookie.domain = domain;
 
     if (!cookieObject.getString(WTF::ASCIILiteral("path"), cookie.path))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'path' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'path' was not found.");
 
     double expires;
     if (!cookieObject.getDouble(WTF::ASCIILiteral("expires"), expires))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'expires' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'expires' was not found.");
 
     cookie.expires = expires * 1000.0;
 
     if (!cookieObject.getBoolean(WTF::ASCIILiteral("secure"), cookie.secure))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'secure' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'secure' was not found.");
 
     if (!cookieObject.getBoolean(WTF::ASCIILiteral("session"), cookie.session))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'session' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'session' was not found.");
 
     if (!cookieObject.getBoolean(WTF::ASCIILiteral("httpOnly"), cookie.httpOnly))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'httpOnly' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'httpOnly' was not found.");
 
     WebCookieManagerProxy* cookieManager = m_processPool->supplement<WebCookieManagerProxy>();
 
@@ -1208,7 +1208,7 @@ void WebAutomationSession::deleteAllCookies(ErrorString& errorString, const Stri
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL());
     ASSERT(activeURL.isValid());
@@ -1234,19 +1234,19 @@ void WebAutomationSession::setSessionPermissions(ErrorString& errorString, const
     for (auto it = permissions.begin(); it != permissions.end(); ++it) {
         RefPtr<JSON::Object> permission;
         if (!it->get()->asObject(permission))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permissions' is invalid.");
+            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permissions' is invalid.");
 
         String permissionName;
         if (!permission->getString(WTF::ASCIILiteral("permission"), permissionName))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' is missing or invalid.");
+            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' is missing or invalid.");
 
         auto parsedPermissionName = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::SessionPermission>(permissionName);
         if (!parsedPermissionName)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' has an unknown value.");
+            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' has an unknown value.");
 
         bool permissionValue;
         if (!permission->getBoolean(WTF::ASCIILiteral("value"), permissionValue))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'value' is missing or invalid.");
+            SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'value' is missing or invalid.");
 
         switch (parsedPermissionName.value()) {
         case Inspector::Protocol::Automation::SessionPermission::GetUserMedia:
@@ -1281,32 +1281,32 @@ static WebEvent::Modifiers protocolModifierToWebEventModifier(Inspector::Protoco
 }
 #endif // USE(APPKIT) || PLATFORM(GTK)
 
-void WebAutomationSession::performMouseInteraction(Inspector::ErrorString& errorString, const String& handle, const JSON::Object& requestedPositionObject, const String& mouseButtonString, const String& mouseInteractionString, const JSON::Array& keyModifierStrings, Ref<PerformMouseInteractionCallback>&& callback)
+void WebAutomationSession::performMouseInteraction(const String& handle, const JSON::Object& requestedPositionObject, const String& mouseButtonString, const String& mouseInteractionString, const JSON::Array& keyModifierStrings, Ref<PerformMouseInteractionCallback>&& callback)
 {
 #if !USE(APPKIT) && !PLATFORM(GTK)
-    FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
+    ASYNC_FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
 #else
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     float x;
     if (!requestedPositionObject.getDouble(WTF::ASCIILiteral("x"), x))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'x' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'x' was not found.");
 
     float y;
     if (!requestedPositionObject.getDouble(WTF::ASCIILiteral("y"), y))
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'y' was not found.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'y' was not found.");
 
     WebEvent::Modifiers keyModifiers = (WebEvent::Modifiers)0;
     for (auto it = keyModifierStrings.begin(); it != keyModifierStrings.end(); ++it) {
         String modifierString;
         if (!it->get()->asString(modifierString))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'modifiers' is invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'modifiers' is invalid.");
 
         auto parsedModifier = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::KeyModifier>(modifierString);
         if (!parsedModifier)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "A modifier in the 'modifiers' array is invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "A modifier in the 'modifiers' array is invalid.");
         WebEvent::Modifiers enumValue = protocolModifierToWebEventModifier(parsedModifier.value());
         keyModifiers = (WebEvent::Modifiers)(enumValue | keyModifiers);
     }
@@ -1320,11 +1320,11 @@ void WebAutomationSession::performMouseInteraction(Inspector::ErrorString& error
 
         auto parsedInteraction = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::MouseInteraction>(mouseInteractionString);
         if (!parsedInteraction)
-            return callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(InvalidParameter, "The parameter 'interaction' is invalid."));
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'interaction' is invalid.");
 
         auto parsedButton = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::MouseButton>(mouseButtonString);
         if (!parsedButton)
-            return callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(InvalidParameter, "The parameter 'button' is invalid."));
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'button' is invalid.");
 
         platformSimulateMouseInteraction(page, viewPosition, parsedInteraction.value(), parsedButton.value(), keyModifiers);
 
@@ -1336,17 +1336,17 @@ void WebAutomationSession::performMouseInteraction(Inspector::ErrorString& error
 #endif // USE(APPKIT) || PLATFORM(GTK)
 }
 
-void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString, const String& handle, const JSON::Array& interactions, Ref<PerformKeyboardInteractionsCallback>&& callback)
+void WebAutomationSession::performKeyboardInteractions(const String& handle, const JSON::Array& interactions, Ref<PerformKeyboardInteractionsCallback>&& callback)
 {
 #if !PLATFORM(COCOA) && !PLATFORM(GTK)
-    FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
+    ASYNC_FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
 #else
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (!interactions.length())
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'interactions' was not found or empty.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'interactions' was not found or empty.");
 
     // Validate all of the parameters before performing any interactions with the browsing context under test.
     Vector<WTF::Function<void()>> actionsToPerform;
@@ -1355,21 +1355,21 @@ void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString,
     for (auto interaction : interactions) {
         RefPtr<JSON::Object> interactionObject;
         if (!interaction->asObject(interactionObject))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter was invalid.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter was invalid.");
 
         String interactionTypeString;
         if (!interactionObject->getString(ASCIILiteral("type"), interactionTypeString))
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter is missing the 'type' key.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter is missing the 'type' key.");
         auto interactionType = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::KeyboardInteractionType>(interactionTypeString);
         if (!interactionType)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'type' key.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'type' key.");
 
         String virtualKeyString;
         bool foundVirtualKey = interactionObject->getString(ASCIILiteral("key"), virtualKeyString);
         if (foundVirtualKey) {
             auto virtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(virtualKeyString);
             if (!virtualKey)
-                FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value.");
+                ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value.");
 
             actionsToPerform.uncheckedAppend([this, page, interactionType, virtualKey] {
                 platformSimulateKeyStroke(*page, interactionType.value(), virtualKey.value());
@@ -1383,7 +1383,7 @@ void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString,
             case Inspector::Protocol::Automation::KeyboardInteractionType::KeyPress:
             case Inspector::Protocol::Automation::KeyboardInteractionType::KeyRelease:
                 // 'KeyPress' and 'KeyRelease' are meant for a virtual key and are not supported for a string (sequence of codepoints).
-                FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value.");
+                ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value.");
 
             case Inspector::Protocol::Automation::KeyboardInteractionType::InsertByKey:
                 actionsToPerform.uncheckedAppend([this, page, keySequence] {
@@ -1394,12 +1394,12 @@ void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString,
         }
 
         if (!foundVirtualKey && !foundKeySequence)
-            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "An interaction in the 'interactions' parameter is missing both 'key' and 'text'. One must be provided.");
+            ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "An interaction in the 'interactions' parameter is missing both 'key' and 'text'. One must be provided.");
     }
 
     ASSERT(actionsToPerform.size());
     if (!actionsToPerform.size())
-        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "No actions to perform.");
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "No actions to perform.");
 
     auto& callbackInMap = m_pendingKeyboardEventsFlushedCallbacksPerPage.add(page->pageID(), nullptr).iterator->value;
     if (callbackInMap)
@@ -1414,15 +1414,15 @@ void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString,
 #endif // PLATFORM(COCOA) || PLATFORM(GTK)
 }
 
-void WebAutomationSession::takeScreenshot(ErrorString& errorString, const String& handle, const String* optionalFrameHandle, const String* optionalNodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* optionalClipToViewport, Ref<TakeScreenshotCallback>&& callback)
+void WebAutomationSession::takeScreenshot(const String& handle, const String* optionalFrameHandle, const String* optionalNodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* optionalClipToViewport, Ref<TakeScreenshotCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString());
     if (!frameID)
-        FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
 
     bool scrollIntoViewIfNeeded = optionalScrollIntoViewIfNeeded ? *optionalScrollIntoViewIfNeeded : false;
     String nodeHandle = optionalNodeHandle ? *optionalNodeHandle : emptyString();
@@ -1446,10 +1446,8 @@ void WebAutomationSession::didTakeScreenshot(uint64_t callbackID, const Shareabl
     }
 
     std::optional<String> base64EncodedData = platformGetBase64EncodedPNGData(imageDataHandle);
-    if (!base64EncodedData) {
-        callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(InternalError));
-        return;
-    }
+    if (!base64EncodedData)
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(InternalError);
 
     callback->sendSuccess(base64EncodedData.value());
 }
index 4f579db..5748459 100644 (file)
@@ -117,41 +117,41 @@ public:
     // and the --platform argument passed to the protocol bindings generator.
 
     // Platform: Generic
-    void getBrowsingContexts(Inspector::ErrorString&, Ref<GetBrowsingContextsCallback>&&) final;
-    void getBrowsingContext(Inspector::ErrorString&, const String&, Ref<GetBrowsingContextCallback>&&) final;
+    void getBrowsingContexts(Ref<GetBrowsingContextsCallback>&&) final;
+    void getBrowsingContext(const String&, Ref<GetBrowsingContextCallback>&&) final;
     void createBrowsingContext(Inspector::ErrorString&, String*) override;
     void closeBrowsingContext(Inspector::ErrorString&, const String&) override;
     void switchToBrowsingContext(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle) override;
-    void setWindowFrameOfBrowsingContext(Inspector::ErrorString&, const String& handle, const JSON::Object* origin, const JSON::Object* size, Ref<SetWindowFrameOfBrowsingContextCallback>&&) final;
-    void navigateBrowsingContext(Inspector::ErrorString&, const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&&) override;
-    void goBackInBrowsingContext(Inspector::ErrorString&, const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&&) override;
-    void goForwardInBrowsingContext(Inspector::ErrorString&, const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoForwardInBrowsingContextCallback>&&) override;
-    void reloadBrowsingContext(Inspector::ErrorString&, const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<ReloadBrowsingContextCallback>&&) override;
-    void waitForNavigationToComplete(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<WaitForNavigationToCompleteCallback>&&) override;
-    void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const JSON::Array& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override;
-    void performMouseInteraction(Inspector::ErrorString&, const String& handle, const JSON::Object& requestedPosition, const String& mouseButton, const String& mouseInteraction, const JSON::Array& keyModifiers, Ref<PerformMouseInteractionCallback>&&) final;
-    void performKeyboardInteractions(Inspector::ErrorString&, const String& handle, const JSON::Array& interactions, Ref<PerformKeyboardInteractionsCallback>&&) override;
-    void takeScreenshot(Inspector::ErrorString&, const String& handle, const String* optionalFrameHandle, const String* optionalNodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* optionalClipToViewport, Ref<TakeScreenshotCallback>&&) override;
-    void resolveChildFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&&) override;
-    void resolveParentFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&&) override;
-    void computeElementLayout(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const String& coordinateSystem, Ref<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>&&) override;
-    void selectOptionElement(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, Ref<Inspector::AutomationBackendDispatcherHandler::SelectOptionElementCallback>&&) override;
+    void setWindowFrameOfBrowsingContext(const String& handle, const JSON::Object* origin, const JSON::Object* size, Ref<SetWindowFrameOfBrowsingContextCallback>&&) final;
+    void navigateBrowsingContext(const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&&) override;
+    void goBackInBrowsingContext(const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&&) override;
+    void goForwardInBrowsingContext(const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoForwardInBrowsingContextCallback>&&) override;
+    void reloadBrowsingContext(const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<ReloadBrowsingContextCallback>&&) override;
+    void waitForNavigationToComplete(const String& browsingContextHandle, const String* optionalFrameHandle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<WaitForNavigationToCompleteCallback>&&) override;
+    void evaluateJavaScriptFunction(const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const JSON::Array& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override;
+    void performMouseInteraction(const String& handle, const JSON::Object& requestedPosition, const String& mouseButton, const String& mouseInteraction, const JSON::Array& keyModifiers, Ref<PerformMouseInteractionCallback>&&) final;
+    void performKeyboardInteractions(const String& handle, const JSON::Array& interactions, Ref<PerformKeyboardInteractionsCallback>&&) override;
+    void takeScreenshot(const String& handle, const String* optionalFrameHandle, const String* optionalNodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* optionalClipToViewport, Ref<TakeScreenshotCallback>&&) override;
+    void resolveChildFrameHandle(const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&&) override;
+    void resolveParentFrameHandle(const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&&) override;
+    void computeElementLayout(const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const String& coordinateSystem, Ref<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>&&) override;
+    void selectOptionElement(const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, Ref<Inspector::AutomationBackendDispatcherHandler::SelectOptionElementCallback>&&) override;
     void isShowingJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, bool* result) override;
     void dismissCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override;
     void acceptCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override;
     void messageOfCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, String* text) override;
     void setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString&, const String& browsingContextHandle, const String& text) override;
     void setFilesToSelectForFileUpload(Inspector::ErrorString&, const String& browsingContextHandle, const JSON::Array& filenames) override;
-    void getAllCookies(Inspector::ErrorString&, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override;
-    void deleteSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override;
-    void addSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const JSON::Object& cookie, Ref<AddSingleCookieCallback>&&) override;
+    void getAllCookies(const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override;
+    void deleteSingleCookie(const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override;
+    void addSingleCookie(const String& browsingContextHandle, const JSON::Object& cookie, Ref<AddSingleCookieCallback>&&) override;
     void deleteAllCookies(Inspector::ErrorString&, const String& browsingContextHandle) override;
     void getSessionPermissions(Inspector::ErrorString&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Automation::SessionPermissionData>>& out_permissions) override;
     void setSessionPermissions(Inspector::ErrorString&, const JSON::Array& in_permissions) override;
 
     // Platform: macOS
 #if PLATFORM(MAC)
-    void inspectBrowsingContext(Inspector::ErrorString&, const String&, const bool* optionalEnableAutoCapturing, Ref<InspectBrowsingContextCallback>&&) override;
+    void inspectBrowsingContext(const String&, const bool* optionalEnableAutoCapturing, Ref<InspectBrowsingContextCallback>&&) override;
 #endif
 
     // Event Simulation Support.
index d639876..2c5db19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define STRING_FOR_PREDEFINED_ERROR_MESSAGE_AND_DETAILS(errorMessage, detailsString) makeString(Inspector::Protocol::AutomationHelpers::getEnumConstantValue(VALIDATED_ERROR_MESSAGE(errorMessage)), errorNameAndDetailsSeparator, detailsString)
 
 // Convenience macros for filling in the error string of synchronous commands in bailout branches.
-#define FAIL_WITH_PREDEFINED_ERROR(errorName) \
+#define SYNC_FAIL_WITH_PREDEFINED_ERROR(errorName) \
 do { \
     errorString = STRING_FOR_PREDEFINED_ERROR_NAME(errorName); \
     return; \
 } while (false)
 
-#define FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(errorName, detailsString) \
+#define SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(errorName, detailsString) \
 do { \
     errorString = STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(errorName, detailsString); \
     return; \
 } while (false)
+
+#define ASYNC_FAIL_WITH_PREDEFINED_ERROR(errorName) \
+do { \
+    callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(errorName)); \
+    return; \
+} while (false)
+
+#define ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(errorName, detailsString) \
+do { \
+    callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(errorName, detailsString)); \
+    return; \
+} while (false)
index e498651..3b5e558 100644 (file)
@@ -44,11 +44,11 @@ namespace WebKit {
 
 #pragma mark Commands for Platform: 'macOS'
 
-void WebAutomationSession::inspectBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const bool* optionalEnableAutoCapturing, Ref<InspectBrowsingContextCallback>&& callback)
+void WebAutomationSession::inspectBrowsingContext(const String& handle, const bool* optionalEnableAutoCapturing, Ref<InspectBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
     if (!page)
-        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
     if (auto callback = m_pendingInspectorCallbacksPerPage.take(page->pageID()))
         callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout));