Skip to content

Commit

Permalink
* Improve websocket connection failure condition handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
iProgramMC committed May 29, 2024
1 parent a263528 commit 3b635c3
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/discord/Frontend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Frontend
// Called by WebSocketClient, dispatches to relevant places including DiscordInstance
virtual void OnWebsocketMessage(int gatewayID, const std::string& payload) = 0;
virtual void OnWebsocketClose(int gatewayID, int errorCode, const std::string& message) = 0;
virtual void OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError) = 0;
virtual void OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError, bool mayRetry) = 0;

// Heartbeat interval
virtual void SetHeartbeatInterval(int timeMs) = 0;
Expand Down
23 changes: 20 additions & 3 deletions src/discord/WebsocketClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,35 @@ void WSConnectionMetadata::OnFail(WSClient* c, websocketpp::connection_hdl hdl)
guiMessage += " (transport error " + xportEc.message() + ")";

namespace SocketErrors = websocketpp::transport::asio::socket::error;
using WebsocketErrors = websocketpp::error::value;

bool isTLSError = false;
switch (pConn->get_ec().value()) {
case SocketErrors::missing_tls_init_handler:
case SocketErrors::tls_failed_sni_hostname:
case SocketErrors::tls_handshake_timeout:
case SocketErrors::tls_handshake_failed:
case SocketErrors::invalid_tls_context:
case SocketErrors::security:
//case SocketErrors::tls_handshake_timeout:
//case SocketErrors::tls_handshake_failed:
isTLSError = true;
}

GetFrontend()->OnWebsocketFail(m_id, pConn->get_ec().value(), guiMessage, isTLSError);
bool mayRetry = false;
switch (pConn->get_ec().value()) {
case WSAHOST_NOT_FOUND:
case WSATRY_AGAIN:
case WSAEDISCON:
case WSAETIMEDOUT:
case SocketErrors::tls_handshake_timeout:
case SocketErrors::tls_handshake_failed:
case WebsocketErrors::bad_connection:
case WebsocketErrors::open_handshake_timeout:
case WebsocketErrors::close_handshake_timeout:
case WebsocketErrors::extension_neg_failed:
mayRetry = true;
}

GetFrontend()->OnWebsocketFail(m_id, pConn->get_ec().value(), guiMessage, isTLSError, mayRetry);
}

void WSConnectionMetadata::OnClose(WSClient* c, websocketpp::connection_hdl hdl)
Expand Down
24 changes: 20 additions & 4 deletions src/windows/Frontend_Win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ void Frontend_Win32::OnWebsocketClose(int gatewayID, int errorCode, const std::s

#include <websocketpp/close.hpp>

void Frontend_Win32::OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError)
void Frontend_Win32::OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError, bool mayRetry)
{
static TCHAR buffer[8192];
LPTSTR msg = ConvertCppStringToTString(message);
Expand All @@ -337,6 +337,7 @@ void Frontend_Win32::OnWebsocketFail(int gatewayID, int errorCode, const std::st
errorCode,
msg
);
free(msg);

if (isTLSError) {
_tcscat(
Expand All @@ -357,10 +358,25 @@ void Frontend_Win32::OnWebsocketFail(int gatewayID, int errorCode, const std::st
);
}

free(msg);
if (mayRetry) {
_tcscat(buffer, TEXT("\n\nClick Retry to try connecting again, or Cancel to quit."));
}

int flags = (mayRetry ? MB_RETRYCANCEL : MB_OK) | (isTLSError ? MB_ICONWARNING : MB_ICONERROR);
int result = MessageBox(g_Hwnd, buffer, TmGetTString(IDS_PROGRAM_NAME), flags);

MessageBox(g_Hwnd, buffer, TmGetTString(IDS_PROGRAM_NAME), (isTLSError ? MB_ICONWARNING : MB_ICONERROR) | MB_OK);
SendMessage(g_Hwnd, WM_CONNECTERROR, 0, 0);
if (mayRetry) {
if (result == IDRETRY) {
SendMessage(g_Hwnd, WM_CONNECTERROR, 0, 0);
}
else {
SendMessage(g_Hwnd, WM_DESTROY, 0, 0);
RequestQuit();
}
}
else {
SendMessage(g_Hwnd, WM_CONNECTERROR2, 0, 0);
}
}

void Frontend_Win32::RequestQuit()
Expand Down
2 changes: 1 addition & 1 deletion src/windows/Frontend_Win32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class Frontend_Win32 : public Frontend
void JumpToMessage(Snowflake messageInCurrentChannel) override;
void OnWebsocketMessage(int gatewayID, const std::string& payload) override;
void OnWebsocketClose(int gatewayID, int errorCode, const std::string& message) override;
void OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError) override;
void OnWebsocketFail(int gatewayID, int errorCode, const std::string& message, bool isTLSError, bool mayRetry) override;
void SetHeartbeatInterval(int timeMs) override;
void LaunchURL(const std::string& url) override;
void RegisterIcon(Snowflake sf, const std::string& avatarlnk) override;
Expand Down
1 change: 1 addition & 0 deletions src/windows/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (g_tryAgainTimerElapse > 10000)
g_tryAgainTimerElapse = 10000;
break;
case WM_CONNECTERROR2:
case WM_CONNECTED:
ResetTryAgainInTime();
if (g_tryAgainTimer) {
Expand Down
1 change: 1 addition & 0 deletions src/windows/WindowMessages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ enum eWmUserMsgs
WM_UPDATEUSER, // Snowflake[1]
WM_UPDATEEMOJI, // Snowflake[1]
WM_TOGGLECHANNELS,
WM_CONNECTERROR2,
};

0 comments on commit 3b635c3

Please sign in to comment.