# Buggy code
def connect(self) -> None:
    try:
        parsed_url = urlparse(self.url.strip())
        hostname: str = parsed_url.hostname
        port: int = parsed_url.port or (443 if parsed_url.scheme == "wss" else 80)
        if self.trace_enabled:
            self.logger.debug(
                f"Connecting to the address for handshake: {hostname}:{port} "
                f"(session id: {self.session_id})"
            )
        sock: Union[ssl.SSLSocket, socket] = _establish_new_socket_connection(
            session_id=self.session_id,
            server_hostname=hostname,
            server_port=port,
            logger=self.logger,
            receive_timeout=self.receive_timeout,
            proxy=self.proxy,
            proxy_headers=self.proxy_headers,
            trace_enabled=self.trace_enabled,
        )

        # WebSocket handshake
        try:
            path = f"{parsed_url.path}?{parsed_url.query}"
            sec_websocket_key = _generate_sec_websocket_key()
            message = f"""GET {path} HTTP/1.1
                    Host: {parsed_url.hostname}
                    Upgrade: websocket
                    Connection: Upgrade
                    Sec-WebSocket-Key: {sec_websocket_key}
                    Sec-WebSocket-Version: 13

                """
            req: str = "\r\n".join([line.lstrip() for line in message.split("\n")])
            if self.trace_enabled:
                self.logger.debug(
                    f"{self.connection_type_name} handshake request (session id: {self.session_id}):\n{req}"
                )
            sock.send(req.encode("utf-8"))
            sock.settimeout(self.receive_timeout)
            status, headers, text = _parse_handshake_response(sock)
            if self.trace_enabled:
                self.logger.debug(
                    f"{self.connection_type_name} handshake response (session id: {self.session_id}):\n{text}"
                )
            # HTTP/1.1 101 Switching Protocols
            if status == 101:
                if not _validate_sec_websocket_accept(sec_websocket_key, headers):
                    raise SlackClientNotConnectedError(
                        f"Invalid response header detected in {self.connection_type_name} handshake response"
                        f" (session id: {self.session_id})"
                    )
                # set this successfully connected socket
                self.sock = sock
                self.ping(f"{self.session_id}:{time.time()}")
            else:
                message = (
                    f"Received an unexpected response for handshake "
                    f"(status: {status}, response: {text}, session id: {self.session_id})"
                )
                self.logger.warning(message)

        except socket.error as e:
            code: Optional[int] = None
            if e.args and len(e.args) > 1 and isinstance(e.args[0], int):
                code = e.args[0]
            if code is not None:
                self.logger.exception(
                    f"Error code: {code} (session id: {self.session_id}, error: {e})"
                )
            raise

    except Exception as e:
        self.logger.exception(
            f"Failed to establish a connection (session id: {self.session_id}, error: {e})"
        )
        self.disconnect()


# Traceback (SlackApiError)
2021-02-14 18:19:49,579 ERROR    slack_sdk.rtm.v2          Failed to establish a connection (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: _ssl.c:1108: The handshake operation timed out)
Traceback (most recent call last):
File "/opt/errbot/lib/python3.8/site-packages/slack_sdk/socket_mode/builtin/connection.py", line 109, in connect
sock.connect((hostname, port))
File "/usr/lib/python3.8/ssl.py", line 1342, in connect
self._real_connect(addr, False)
File "/usr/lib/python3.8/ssl.py", line 1333, in _real_connect
self.do_handshake()
File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
socket.timeout: _ssl.c:1108: The handshake operation timed out
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          The connection has been closed (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          The connection has been closed (session id: b88f63ee-d644-45a8-bf18-be36c8673728)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          A new session has been established (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          Connected to a new endpoint...
2021-02-14 18:19:59,590 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:59,590 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:59,590 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:00,075 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:00,075 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:10,092 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:10,117 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:10,121 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:10,339 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:10,339 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:20,350 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:20,350 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:20,350 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:20,556 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:20,557 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:30,567 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:30,567 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:30,567 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...

# Fixed code
def connect(self) -> None:
    try:
        parsed_url = urlparse(self.url.strip())
        hostname: str = parsed_url.hostname
        port: int = parsed_url.port or (443 if parsed_url.scheme == "wss" else 80)
        if self.trace_enabled:
            self.logger.debug(
                f"Connecting to the address for handshake: {hostname}:{port} "
                f"(session id: {self.session_id})"
            )
        sock: Union[ssl.SSLSocket, socket] = _establish_new_socket_connection(
            session_id=self.session_id,
            server_hostname=hostname,
            server_port=port,
            logger=self.logger,
            sock_send_lock=self.sock_send_lock,
            receive_timeout=self.receive_timeout,
            proxy=self.proxy,
            proxy_headers=self.proxy_headers,
            trace_enabled=self.trace_enabled,
        )

        # WebSocket handshake
        try:
            path = f"{parsed_url.path}?{parsed_url.query}"
            sec_websocket_key = _generate_sec_websocket_key()
            message = f"""GET {path} HTTP/1.1
                    Host: {parsed_url.hostname}
                    Upgrade: websocket
                    Connection: Upgrade
                    Sec-WebSocket-Key: {sec_websocket_key}
                    Sec-WebSocket-Version: 13

                """
            req: str = "\r\n".join([line.lstrip() for line in message.split("\n")])
            if self.trace_enabled:
                self.logger.debug(
                    f"{self.connection_type_name} handshake request (session id: {self.session_id}):\n{req}"
                )
            with self.sock_send_lock:
                sock.send(req.encode("utf-8"))

            status, headers, text = _parse_handshake_response(sock)
            if self.trace_enabled:
                self.logger.debug(
                    f"{self.connection_type_name} handshake response (session id: {self.session_id}):\n{text}"
                )
            # HTTP/1.1 101 Switching Protocols
            if status == 101:
                if not _validate_sec_websocket_accept(sec_websocket_key, headers):
                    raise SlackClientNotConnectedError(
                        f"Invalid response header detected in {self.connection_type_name} handshake response"
                        f" (session id: {self.session_id})"
                    )
                # set this successfully connected socket
                self.sock = sock
                self.ping(f"{self.session_id}:{time.time()}")
            else:
                message = (
                    f"Received an unexpected response for handshake "
                    f"(status: {status}, response: {text}, session id: {self.session_id})"
                )
                self.logger.warning(message)

        except socket.error as e:
            code: Optional[int] = None
            if e.args and len(e.args) > 1 and isinstance(e.args[0], int):
                code = e.args[0]
            if code is not None:
                self.logger.exception(
                    f"Error code: {code} (session id: {self.session_id}, error: {e})"
                )
            raise

    except Exception as e:
        self.logger.exception(
            f"Failed to establish a connection (session id: {self.session_id}, error: {e})"
        )
        self.disconnect()