浏览代码

Emit AbstractClient::error signal on unattached channel

Viktor Kopp 5 年之前
父节点
当前提交
9eff09f395
共有 4 个文件被更改,包括 38 次插入37 次删除
  1. 19 22
      src/grpc/abstractclient.cpp
  2. 8 0
      src/grpc/abstractclient.h
  3. 2 3
      src/grpc/http2channel.cpp
  4. 9 12
      tests/test_grpc/clienttest.cpp

+ 19 - 22
src/grpc/abstractclient.cpp

@@ -60,40 +60,37 @@ void AbstractClient::attachChannel(const std::shared_ptr<AbstractChannel> &chann
 
 bool AbstractClient::call(const QString &method, const QByteArray &arg, QByteArray &ret)
 {
-    if (!d->channel) {
-        d->lastError = AbstractChannel::Unknown;
-        return false;
+    AbstractChannel::StatusCode callStatus = AbstractChannel::Unknown;
+    if (d->channel) {
+        callStatus = d->channel->call(method, d->service, arg, ret);
+    } else {
+        emit error(callStatus, QLatin1String("No channel(s) attached."));
     }
 
-    d->lastError = d->channel->call(method, d->service, arg, ret);
-    return d->lastError == AbstractChannel::Ok;
+    return AbstractChannel::Ok == callStatus;
 }
 
 AsyncReply *AbstractClient::call(const QString &method, const QByteArray &arg)
 {
-    AsyncReply *reply = new AsyncReply(d->channel, this);
+    AsyncReply *reply = nullptr;
+    if (d->channel) {
+        reply = new AsyncReply(d->channel, this);
 
-    if (!d->channel) {
-        d->lastError = AbstractChannel::Unknown;
-        d->lastErrorString = "No channel attached";
-        QTimer::singleShot(0, this, [reply]() {
-            reply->error(AbstractChannel::Unknown);
+        connect(reply, &AsyncReply::error, this, [this, reply](AbstractChannel::StatusCode statusCode) {
+            d->lastError = statusCode;
+            emit error(statusCode, QLatin1String("Connection has been aborted."));
             reply->deleteLater();
         });
-        return reply;
-    }
 
-    connect(reply, &AsyncReply::error, this, [this, reply](AbstractChannel::StatusCode statusCode){
-        d->lastError = statusCode;
-        reply->deleteLater();
-    });
+        connect(reply, &AsyncReply::finished, this, [reply](){
+            reply->deleteLater();
+        });
 
-    connect(reply, &AsyncReply::finished, this, [this, reply](){
-        reply->deleteLater();
-    });
+        d->channel->call(method, d->service, arg, reply);
+    } else {
+        emit error(AbstractChannel::Unknown, QLatin1String("No channel(s) attached."));
+    }
 
-    d->lastError = AbstractChannel::Ok;//Assume that all is OK until something happened
-    d->channel->call(method, d->service, arg, reply);
     return reply;
 }
 

+ 8 - 0
src/grpc/abstractclient.h

@@ -45,6 +45,7 @@ class AbstractChannel;
 
 class QTGRPCSHARED_EXPORT AbstractClient : public QObject
 {
+    Q_OBJECT
 public:
     void attachChannel(const std::shared_ptr<AbstractChannel> &channel);
 
@@ -62,6 +63,13 @@ protected:
     AbstractClient(const QString &service, QObject *parent = nullptr);
     virtual ~AbstractClient();
 
+    /**
+     * @brief A template of a sync RPC call
+     *
+     * @param method Name of the method to be called
+     * @param arg Arguments (proto-message) passed to the method called
+     * @param ret A pointer to memory with proto-message to write an RPC reply to
+     */
     template<typename A, typename R>
     bool call(const QString &method, const A &arg, const QPointer<R> &ret) {
         if (ret.isNull()) {

+ 2 - 3
src/grpc/http2channel.cpp

@@ -157,7 +157,6 @@ struct Http2ChannelPrivate {
     static QByteArray processReply(QNetworkReply *networkReply, AbstractChannel::StatusCode &statusCode) {
         //Check if no network error occured
         if (networkReply->error() != QNetworkReply::NoError) {
-            qProtoWarning() << networkReply->error() << ":" << networkReply->errorString();
             statusCode = StatusCodeMap.at(networkReply->error());
             return {};
         }
@@ -165,7 +164,6 @@ struct Http2ChannelPrivate {
         //Check if server answer with error
         statusCode = static_cast<AbstractChannel::StatusCode>(networkReply->rawHeader(GrpcStatusHeader).toInt());
         if (statusCode != AbstractChannel::StatusCode::Ok) {
-            qProtoWarning() << "Protobuf server error occured" << networkReply->errorString();
             return {};
         }
 
@@ -246,6 +244,7 @@ void Http2Channel::call(const QString &method, const QString &service, const QBy
     auto connection = QObject::connect(networkReply, &QNetworkReply::finished, reply, [reply, networkReply]() {
         StatusCode grpcStatus = StatusCode::Unknown;
         QByteArray data = Http2ChannelPrivate::processReply(networkReply, grpcStatus);
+
         qProtoDebug() << "RECV: " << data;
         if (grpcStatus != StatusCode::Ok) {
             reply->setData({});
@@ -257,7 +256,7 @@ void Http2Channel::call(const QString &method, const QString &service, const QBy
         reply->finished();
     });
 
-    QObject::connect(reply, &AsyncReply::error, networkReply, [reply, networkReply, connection]() {
+    QObject::connect(reply, &AsyncReply::error, networkReply, [networkReply, connection](AbstractChannel::StatusCode code) {
         QObject::disconnect(connection);
         Http2ChannelPrivate::abortNetworkReply(networkReply);
     });

+ 9 - 12
tests/test_grpc/clienttest.cpp

@@ -126,30 +126,27 @@ TEST_F(ClientTest, StringEchoAsyncAbortTest)
     SimpleStringMessage request;
     request.setTestFieldString("sleep");
     QEventLoop waiter;
-
-    bool errorCalled = false;
     AsyncReply *reply = testClient.testMethod(request);
+
     result.setTestFieldString("Result not changed by echo");
-    QObject::connect(reply, &AsyncReply::finished, &m_app, [reply, &result, &waiter, &testClient]() {
-        if (testClient.lastError() == AbstractChannel::StatusCode::Ok) {
-            result = reply->read<SimpleStringMessage>();
-        }
+    QObject::connect(reply, &AsyncReply::finished, &m_app, [&waiter]() {
         waiter.quit();
     });
 
-    QObject::connect(reply, &AsyncReply::error, reply, [&errorCalled](AbstractChannel::StatusCode){
-        errorCalled = true;
+    AbstractChannel::StatusCode asyncStatus = AbstractChannel::StatusCode::Ok;
+    QObject::connect(reply, &AsyncReply::error, reply, [&asyncStatus](AbstractChannel::StatusCode code){
+        asyncStatus = code;
     });
     QTimer::singleShot(5000, &waiter, &QEventLoop::quit);
     reply->abort();
 
     waiter.exec();
-    ASSERT_STREQ(result.testFieldString().toStdString().c_str(), "Result not changed by echo");
     ASSERT_EQ(testClient.lastError(), AbstractChannel::StatusCode::Aborted);
-    ASSERT_TRUE(errorCalled);
-
+    ASSERT_EQ(asyncStatus, AbstractChannel::StatusCode::Aborted);
+    ASSERT_STREQ(result.testFieldString().toStdString().c_str(), "Result not changed by echo");
 
-    errorCalled = false;
+    // What we check here?
+    bool errorCalled = false;
     reply = testClient.testMethod(request);
     QObject::connect(reply, &AsyncReply::finished, &m_app, [reply, &result, &waiter, &testClient]() {
         if (testClient.lastError() == AbstractChannel::StatusCode::Ok) {