diff --git a/app/backend/computermanager.cpp b/app/backend/computermanager.cpp index 8431799b..3969bd08 100644 --- a/app/backend/computermanager.cpp +++ b/app/backend/computermanager.cpp @@ -400,6 +400,8 @@ private: } } catch (const GfeHttpResponseException& e) { emit pairingCompleted(m_Computer, e.toQString()); + } catch (const QtNetworkReplyException& e) { + emit pairingCompleted(m_Computer, e.toQString()); } } @@ -452,6 +454,12 @@ private: else { emit quitAppFailed(e.toQString()); } + } catch (const QtNetworkReplyException& e) { + { + QWriteLocker lock(&m_Computer->lock); + m_Computer->pendingQuit = false; + } + emit quitAppFailed(e.toQString()); } } @@ -535,7 +543,24 @@ private: QString serverInfo; try { - serverInfo = http.getServerInfo(NvHTTP::NvLogLevel::VERBOSE); + // There's a race condition between GameStream servers reporting presence over + // mDNS and the HTTPS server being ready to respond to our queries. To work + // around this issue, we will issue the request again after a few seconds if + // we see a ServiceUnavailableError error. + try { + serverInfo = http.getServerInfo(NvHTTP::NvLogLevel::VERBOSE); + } catch (const QtNetworkReplyException& e) { + if (e.getError() == QNetworkReply::ServiceUnavailableError) { + qWarning() << "Retrying request in 5 seconds after ServiceUnavailableError"; + QThread::sleep(5); + serverInfo = http.getServerInfo(NvHTTP::NvLogLevel::VERBOSE); + qInfo() << "Retry successful"; + } + else { + // Rethrow other errors + throw e; + } + } } catch (...) { if (!m_Mdns) { emit computerAddCompleted(false); diff --git a/app/backend/nvhttp.cpp b/app/backend/nvhttp.cpp index 1e59e04a..4d89a921 100644 --- a/app/backend/nvhttp.cpp +++ b/app/backend/nvhttp.cpp @@ -419,7 +419,7 @@ NvHTTP::openConnection(QUrl baseUrl, if (logLevel >= NvLogLevel::ERROR) { qWarning() << command << " request failed with error " << reply->error(); } - GfeHttpResponseException exception(reply->error(), reply->errorString()); + QtNetworkReplyException exception(reply->error(), reply->errorString()); delete reply; throw exception; } diff --git a/app/backend/nvhttp.h b/app/backend/nvhttp.h index bc033a9e..ae9576d3 100644 --- a/app/backend/nvhttp.h +++ b/app/backend/nvhttp.h @@ -5,7 +5,8 @@ #include #include -#include +#include +#include class NvApp { @@ -52,7 +53,7 @@ public: } - const char* what() const throw() + const char* what() const { return m_StatusMessage.toLatin1(); } @@ -77,6 +78,41 @@ private: QString m_StatusMessage; }; +class QtNetworkReplyException : public std::exception +{ +public: + QtNetworkReplyException(QNetworkReply::NetworkError error, QString errorText) : + m_Error(error), + m_ErrorText(errorText) + { + + } + + const char* what() const + { + return m_ErrorText.toLatin1(); + } + + const char* getErrorText() const + { + return m_ErrorText.toLatin1(); + } + + QNetworkReply::NetworkError getError() const + { + return m_Error; + } + + QString toQString() const + { + return m_ErrorText + " (Error " + QString::number(m_Error) + ")"; + } + +private: + QNetworkReply::NetworkError m_Error; + QString m_ErrorText; +}; + class NvHTTP { public: diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index d1ad45e7..3bf557a8 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -779,6 +779,10 @@ void Session::exec(int displayOriginX, int displayOriginY) emit displayLaunchError(e.toQString()); s_ActiveSessionSemaphore.release(); return; + } catch (const QtNetworkReplyException& e) { + emit displayLaunchError(e.toQString()); + s_ActiveSessionSemaphore.release(); + return; } SDL_assert(!SDL_WasInit(SDL_INIT_VIDEO));