Index: lib/DispatcherBase_cpp.template |
diff --git a/lib/DispatcherBase_cpp.template b/lib/DispatcherBase_cpp.template |
index 76f77aae7ece7871d2db5e64aa626ea8f308a208..c4f36a5fd31b286d8c9ad99b328b65017571efa5 100644 |
--- a/lib/DispatcherBase_cpp.template |
+++ b/lib/DispatcherBase_cpp.template |
@@ -10,7 +10,45 @@ namespace {{namespace}} { |
{% endfor %} |
// static |
-const char DispatcherBase::kInvalidRequest[] = "Invalid request"; |
+DispatchResponse DispatchResponse::OK() |
+{ |
+ DispatchResponse result; |
+ result.m_status = kSuccess; |
+ result.m_errorCode = kParseError; |
+ return result; |
+} |
+ |
+// static |
+DispatchResponse DispatchResponse::Error(const String& error) |
+{ |
+ DispatchResponse result; |
+ result.m_status = kError; |
+ result.m_errorCode = kServerError; |
+ result.m_errorMessage = error; |
+ return result; |
+} |
+ |
+// static |
+DispatchResponse DispatchResponse::InternalError() |
+{ |
+ DispatchResponse result; |
+ result.m_status = kError; |
+ result.m_errorCode = kInternalError; |
+ result.m_errorMessage = "Internal error"; |
+ return result; |
+} |
+ |
+// static |
+DispatchResponse DispatchResponse::FallThrough() |
+{ |
+ DispatchResponse result; |
+ result.m_status = kFallThrough; |
+ result.m_errorCode = kParseError; |
+ return result; |
+} |
+ |
+// static |
+const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters"; |
DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { } |
@@ -31,11 +69,11 @@ void DispatcherBase::Callback::dispose() |
m_backendImpl = nullptr; |
} |
-void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError) |
+void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response) |
{ |
if (!m_backendImpl || !m_backendImpl->get()) |
return; |
- m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::move(partialMessage)); |
+ m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage)); |
m_backendImpl = nullptr; |
} |
@@ -64,10 +102,10 @@ bool DispatcherBase::getCommandName(const String& message, String* result) |
return true; |
} |
-void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) |
+void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result) |
{ |
- if (invocationError.length() || (errors && errors->hasErrors())) { |
- reportProtocolError(callId, ServerError, invocationError, errors); |
+ if (response.status() == DispatchResponse::kError) { |
+ reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr); |
return; |
} |
@@ -78,24 +116,18 @@ void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError |
m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONString()); |
} |
-void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, std::unique_ptr<protocol::DictionaryValue> result) |
+void DispatcherBase::sendResponse(int callId, const DispatchResponse& response) |
{ |
- sendResponse(callId, invocationError, nullptr, std::move(result)); |
+ sendResponse(callId, response, DictionaryValue::create()); |
} |
-void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError) |
-{ |
- sendResponse(callId, invocationError, nullptr, DictionaryValue::create()); |
-} |
- |
-static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatcherBase::CommonErrorCode code, const String& errorMessage, ErrorSupport* errors) |
+static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors) |
{ |
if (!frontendChannel) |
return; |
std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create(); |
error->setInteger("code", code); |
error->setString("message", errorMessage); |
- DCHECK(error); |
if (errors && errors->hasErrors()) |
error->setString("data", errors->errors()); |
std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create(); |
@@ -104,7 +136,19 @@ static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, |
frontendChannel->sendProtocolResponse(callId, message->toJSONString()); |
} |
-void DispatcherBase::reportProtocolError(int callId, CommonErrorCode code, const String& errorMessage, ErrorSupport* errors) |
+static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage) |
+{ |
+ if (!frontendChannel) |
+ return; |
+ std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create(); |
+ error->setInteger("code", code); |
+ error->setString("message", errorMessage); |
+ std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create(); |
+ message->setObject("error", std::move(error)); |
+ frontendChannel->sendProtocolNotification(message->toJSONString()); |
+} |
+ |
+void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors) |
{ |
reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors); |
} |
@@ -132,38 +176,46 @@ void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protoco |
m_dispatchers[name] = std::move(dispatcher); |
} |
-void UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage) |
+DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage) |
{ |
- if (!parsedMessage) |
- return; |
+ if (!parsedMessage) { |
+ reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON"); |
+ return DispatchResponse::kError; |
+ } |
std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage)); |
- if (!messageObject) |
- return; |
+ if (!messageObject) { |
+ reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object"); |
+ return DispatchResponse::kError; |
+ } |
int callId = 0; |
protocol::Value* callIdValue = messageObject->get("id"); |
bool success = callIdValue && callIdValue->asInteger(&callId); |
- if (!success) |
- return; |
+ if (!success) { |
+ reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' porperty"); |
+ return DispatchResponse::kError; |
+ } |
protocol::Value* methodValue = messageObject->get("method"); |
String method; |
success = methodValue && methodValue->asString(&method); |
- if (!success) |
- return; |
+ if (!success) { |
+ reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' porperty", nullptr); |
+ return DispatchResponse::kError; |
+ } |
size_t dotIndex = method.find("."); |
if (dotIndex == StringUtil::kNotFound) { |
- reportProtocolErrorTo(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); |
- return; |
+ reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr); |
+ return DispatchResponse::kError; |
} |
String domain = StringUtil::substring(method, 0, dotIndex); |
auto it = m_dispatchers.find(domain); |
if (it == m_dispatchers.end()) { |
- reportProtocolErrorTo(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); |
- return; |
+ reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr); |
+ return DispatchResponse::kError; |
} |
- it->second->dispatch(callId, method, std::move(messageObject)); |
+ return it->second->dispatch(callId, method, std::move(messageObject)); |
} |
UberDispatcher::~UberDispatcher() = default; |