From f8ebd4fd9a59bcb34a6ce45ce1f0b4a22beae884 Mon Sep 17 00:00:00 2001 From: Shane Synan Date: Tue, 6 Sep 2016 16:33:58 -0500 Subject: [PATCH] Show IRC server error messages when unexpected Handle ERROR replies from IRC servers, displaying the error message in the status buffer. Add method 'disconnectExpected' to CoreNetwork to expose when a disconnect is expected. As we're expecting a server error message when issuing QUIT, hide it to avoid showing redundant information. This fixes users getting disconnected by the server without any way to find out why. Resolves GH-238. (cherry picked from commit 56b2bf3a1a742971a5de7ced1b57024424fc78b8) --- src/common/eventmanager.h | 1 + src/core/corenetwork.h | 9 +++++++++ src/core/coresessioneventprocessor.cpp | 15 +++++++++++++++ src/core/coresessioneventprocessor.h | 1 + src/core/eventstringifier.cpp | 9 +++++++++ src/core/eventstringifier.h | 1 + 6 files changed, 36 insertions(+) diff --git a/src/common/eventmanager.h b/src/common/eventmanager.h index ec140649..31cc42e0 100644 --- a/src/common/eventmanager.h +++ b/src/common/eventmanager.h @@ -101,6 +101,7 @@ public : IrcEventPrivmsg, IrcEventQuit, IrcEventTopic, + IrcEventError, /// ERROR message from server IrcEventWallops, IrcEventRawPrivmsg, ///< Undecoded privmsg (still needs CTCP parsing) IrcEventRawNotice, ///< Undecoded notice (still needs CTCP parsing) diff --git a/src/core/corenetwork.h b/src/core/corenetwork.h index 5a41b983..77715279 100644 --- a/src/core/corenetwork.h +++ b/src/core/corenetwork.h @@ -98,6 +98,15 @@ public: inline quint16 localPort() const { return socket.localPort(); } inline quint16 peerPort() const { return socket.peerPort(); } + /** + * Gets whether or not a disconnect was expected. + * + * Distinguishes desired quits from unexpected disconnections such as socket errors or timeouts. + * + * @return True if disconnect was requested, otherwise false. + */ + inline bool disconnectExpected() const { return _disconnectExpected; } + QList> splitMessage(const QString &cmd, const QString &message, std::function(QString &)> cmdGenerator); public slots: diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index ad598903..ed2904cb 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -449,6 +449,21 @@ void CoreSessionEventProcessor::processIrcEventTopic(IrcEvent *e) } } +/* ERROR - "ERROR :reason" +Example: ERROR :Closing Link: nickname[xxx.xxx.xxx.xxx] (Large base64 image paste.) +See https://tools.ietf.org/html/rfc2812#section-3.7.4 */ +void CoreSessionEventProcessor::processIrcEventError(IrcEvent *e) +{ + if (!checkParamCount(e, 1)) + return; + + if (coreNetwork(e)->disconnectExpected()) { + // During QUIT, the server should send an error (often, but not always, "Closing Link"). As + // we're expecting it, don't show this to the user. + e->setFlag(EventManager::Silent); + } +} + #ifdef HAVE_QCA2 void CoreSessionEventProcessor::processKeyEvent(KeyEvent *e) diff --git a/src/core/coresessioneventprocessor.h b/src/core/coresessioneventprocessor.h index 43e6754c..554cab74 100644 --- a/src/core/coresessioneventprocessor.h +++ b/src/core/coresessioneventprocessor.h @@ -59,6 +59,7 @@ public: Q_INVOKABLE void processIrcEventQuit(IrcEvent *event); Q_INVOKABLE void lateProcessIrcEventQuit(IrcEvent *event); Q_INVOKABLE void processIrcEventTopic(IrcEvent *event); + Q_INVOKABLE void processIrcEventError(IrcEvent *event); /// ERROR message from server #ifdef HAVE_QCA2 Q_INVOKABLE void processKeyEvent(KeyEvent *event); #endif diff --git a/src/core/eventstringifier.cpp b/src/core/eventstringifier.cpp index 943727cd..66f0e274 100644 --- a/src/core/eventstringifier.cpp +++ b/src/core/eventstringifier.cpp @@ -342,6 +342,15 @@ void EventStringifier::processIrcEventTopic(IrcEvent *e) .arg(e->nick(), e->params().at(0), e->params().at(1)), QString(), e->params().at(0)); } +void EventStringifier::processIrcEventError(IrcEvent *e) +{ + // Need an error reason + if (!checkParamCount(e, 1)) + return; + + displayMsg(e, Message::Server, tr("Error from server: ") + e->params().join("")); +} + void EventStringifier::processIrcEventWallops(IrcEvent *e) { displayMsg(e, Message::Server, tr("[Operwall] %1: %2").arg(e->nick(), e->params().join(" "))); diff --git a/src/core/eventstringifier.h b/src/core/eventstringifier.h index 7c4c86d3..4cfae10e 100644 --- a/src/core/eventstringifier.h +++ b/src/core/eventstringifier.h @@ -64,6 +64,7 @@ public: Q_INVOKABLE void processIrcEventPong(IrcEvent *event); Q_INVOKABLE void processIrcEventQuit(IrcEvent *event); Q_INVOKABLE void processIrcEventTopic(IrcEvent *event); + Q_INVOKABLE void processIrcEventError(IrcEvent *event); /// ERROR message from server Q_INVOKABLE void processIrcEventWallops(IrcEvent *event); Q_INVOKABLE void processIrcEvent005(IrcEvent *event); // RPL_ISUPPORT -- 2.20.1