Skip to content

Commit

Permalink
Provide better messages for socket errors
Browse files Browse the repository at this point in the history
Logging the error code and, if no message is available, using the
internal enum name instead. If there was a proxy error, inform the user
that they can disable the application proxy in the preferences.

Relates to #1360.
  • Loading branch information
askmeaboutlo0m committed Aug 17, 2024
1 parent 96b3364 commit 83ece45
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Unreleased Version 2.2.2-pre
* Fix: Solve rendering glitches with selection outlines that happen on some systems. Thanks xxxx for reporting.
* Feature: Allow scaling animation exports. Thanks Hopfel for animating across a giant canvas.
* Fix: Allow disabling the application proxy in the network preferences and automatically detect bad proxy configurations that can't actually make connections. Thanks FishEggsThe for reporting.
* Fix: Improve socket error messages, listing the error code and adding extra information on what to do if a proxy error occurs. Thanks FishEggsThe for reporting.

2024-08-09 Version 2.2.2-beta.3
* Fix: Use more accurate timers for performance profiles if the platform supports it.
Expand Down
50 changes: 43 additions & 7 deletions src/libclient/net/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "libshared/net/servercmd.h"
#include "libshared/util/whatismyip.h"
#include <QDebug>
#include <QMetaEnum>
#include <QUrlQuery>
#ifdef HAVE_TCPSOCKETS
# include "libclient/net/tcpserver.h"
Expand All @@ -15,8 +16,8 @@

namespace net {

Server *Server::make(
const QUrl &url, int timeoutSecs, int proxyMode, Client *client)
Server *
Server::make(const QUrl &url, int timeoutSecs, int proxyMode, Client *client)
{
#if defined(HAVE_WEBSOCKETS) && defined(HAVE_TCPSOCKETS)
if(url.scheme().startsWith(QStringLiteral("ws"), Qt::CaseInsensitive)) {
Expand Down Expand Up @@ -177,11 +178,27 @@ void Server::handleSocketStateChange(QAbstractSocket::SocketState state)

void Server::handleSocketError()
{
QString errorString = socketErrorString();
QString errorString = socketErrorStringWithCode();
qWarning() << "Socket error:" << errorString;
if(socketError() != QAbstractSocket::RemoteHostClosedError) {
QAbstractSocket::SocketError errorCode = socketError();
if(errorCode != QAbstractSocket::RemoteHostClosedError) {
if(m_error.isEmpty()) {
m_error = socketErrorString();
m_error = errorString;
switch(errorCode) {
case QAbstractSocket::ProxyAuthenticationRequiredError:
case QAbstractSocket::ProxyConnectionRefusedError:
case QAbstractSocket::ProxyConnectionClosedError:
case QAbstractSocket::ProxyConnectionTimeoutError:
case QAbstractSocket::ProxyNotFoundError:
case QAbstractSocket::ProxyProtocolError:
m_error += QStringLiteral("\n\n") +
tr("If you don't intend to use a proxy, you can "
"disable the network proxy in Drawpile's "
"preferences under the Network tab.");
break;
default:
break;
}
}

if(isConnected()) {
Expand All @@ -194,7 +211,7 @@ void Server::handleSocketError()

void Server::handleReadError()
{
QString errorString = socketErrorString();
QString errorString = socketErrorStringWithCode();
qWarning() << "Socket read error:" << errorString;
if(m_error.isEmpty()) {
if(errorString.isEmpty()) {
Expand All @@ -207,7 +224,7 @@ void Server::handleReadError()

void Server::handleWriteError()
{
QString errorString = socketErrorString();
QString errorString = socketErrorStringWithCode();
qWarning() << "Socket write error:" << errorString;
if(m_error.isEmpty()) {
if(errorString.isEmpty()) {
Expand Down Expand Up @@ -337,4 +354,23 @@ void Server::loginFailure(const QString &message, const QString &errorcode)
disconnectFromHost();
}

QString Server::socketErrorStringWithCode() const
{
int errorCode = int(socketError());
QString errorString = socketErrorString();
if(errorString.isEmpty()) {
const char *errorCodeKey =
QMetaEnum::fromType<QAbstractSocket::SocketError>().key(errorCode);
QString errorCodeString = errorCodeKey ? QString::fromUtf8(errorCodeKey)
: QStringLiteral("Invalid");
//: This is a network socket error message. %1 is an error code number,
//: %2 is the English name for the error code.
return tr("Socket error %1: %2").arg(errorCode).arg(errorCodeString);
} else {
//: This is a network socket error message. %1 is the error message, %2
//: is an error code number.
return tr("%1 (error %2)").arg(errorString).arg(errorCode);
}
}

}
2 changes: 2 additions & 0 deletions src/libclient/net/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ private slots:
void loginSuccess();
void loginFailure(const QString &message, const QString &errorcode);

QString socketErrorStringWithCode() const;

Client *const m_client;
net::MessageList m_receiveBuffer;
LoginHandler *m_loginstate = nullptr;
Expand Down

0 comments on commit 83ece45

Please sign in to comment.