From 7478c97ccd4d91e64a085a7c4ff226aeabeb5aee Mon Sep 17 00:00:00 2001 From: Tayou Date: Thu, 4 Jun 2026 21:17:03 +0200 Subject: [PATCH] on server errors, treat account as offline Signed-off-by: Tayou (cherry picked from commit 0a3adb7912101e0ba29e97a998e97a3e08146f1b) --- .../minecraft/auth/steps/LauncherLoginStep.cpp | 2 +- .../minecraft/auth/steps/MinecraftProfileStep.cpp | 2 +- .../minecraft/auth/steps/XboxAuthorizationStep.cpp | 2 +- launcher/minecraft/auth/steps/XboxUserStep.cpp | 2 +- launcher/net/NetUtils.h | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp index 89293c22e..701261b52 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp @@ -56,7 +56,7 @@ void LauncherLoginStep::onRequestDone(QByteArray* response) qCDebug(authCredentials()) << *response; if (m_request->error() != QNetworkReply::NoError) { qWarning() << "Reply error:" << m_request->error(); - if (Net::isApplicationError(m_request->error())) { + if (Net::isApplicationError(m_request->error()) && !Net::isServerError(m_request->error())) { emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to get Minecraft access token: %1").arg(m_request->errorString())); } else { diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp index 418c46a0e..7e089cf86 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp @@ -52,7 +52,7 @@ void MinecraftProfileStep::onRequestDone(QByteArray* response) qWarning() << " Response:"; qWarning() << QString::fromUtf8(*response); - if (Net::isApplicationError(m_request->error())) { + if (Net::isApplicationError(m_request->error()) && !Net::isServerError(m_request->error())) { emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Minecraft Java profile acquisition failed: %1").arg(m_request->errorString())); } else { diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp index 84320c7c1..4890f4da1 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp @@ -60,7 +60,7 @@ void XboxAuthorizationStep::onRequestDone(QByteArray* response) qCDebug(authCredentials()) << *response; if (m_request->error() != QNetworkReply::NoError) { qWarning() << "Reply error:" << m_request->error(); - if (Net::isApplicationError(m_request->error())) { + if (Net::isApplicationError(m_request->error()) && !Net::isServerError(m_request->error())) { if (processSTSError(*response)) { return; } diff --git a/launcher/minecraft/auth/steps/XboxUserStep.cpp b/launcher/minecraft/auth/steps/XboxUserStep.cpp index 97544d09b..e2971dcd9 100644 --- a/launcher/minecraft/auth/steps/XboxUserStep.cpp +++ b/launcher/minecraft/auth/steps/XboxUserStep.cpp @@ -56,7 +56,7 @@ void XboxUserStep::onRequestDone(QByteArray* response) { if (m_request->error() != QNetworkReply::NoError) { qWarning() << "Reply error:" << m_request->error(); - if (Net::isApplicationError(m_request->error())) { + if (Net::isApplicationError(m_request->error()) && !Net::isServerError(m_request->error())) { emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Xbox user authentication failed: %1").arg(m_request->errorString())); } else { emit finished(AccountTaskState::STATE_OFFLINE, tr("Xbox user authentication failed: %1").arg(m_request->errorString())); diff --git a/launcher/net/NetUtils.h b/launcher/net/NetUtils.h index cd517bcca..67ebc9685 100644 --- a/launcher/net/NetUtils.h +++ b/launcher/net/NetUtils.h @@ -40,4 +40,18 @@ inline bool isApplicationError(QNetworkReply::NetworkError x) QNetworkReply::UnknownContentError }; return errors.contains(x); } + +// 500 class errors, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/500 +// microsoft may send these error codes when services (auth) are down. +// We treat this as a reason to launch in offline mode. +inline bool isServerError(QNetworkReply::NetworkError x) +{ + static QSet errors = { QNetworkReply::InternalServerError, + QNetworkReply::OperationNotImplementedError, + QNetworkReply::ServiceUnavailableError, // 503 | seen in logs in 2026 + //QNetworkReply::GatewayTimeoutError, // 504 | seen in logs in 2024 + // Qt doesn't have it mapped. Unknown covers it + QNetworkReply::UnknownServerError }; + return errors.contains(x); +} } // namespace Net