Search code examples
pythonexceptionconnectionsuds

how to identify connection error in python?


In python we get different exception for diff connection issues like ECONNREFUSED, ECONNRESET, EHOSTUNREACH etc. Is there any standard logic for identifying connection errors in python? Basically I am using suds for connecting to vmware WS SDK and I want to re-try session login on connection errors.


Solution

  • I faced exactly this problem today and I wrote a blog post about it: https://gmpy.dev/blog/2023/recognize-connection-errors

    import errno, socket, ssl
    
    # Network errors, usually related to DHCP or wpa_supplicant (Wi-Fi).
    NETWORK_ERRNOS = frozenset((
        errno.ENETUNREACH,  # "Network is unreachable"
        errno.ENETDOWN,  # "Network is down"
        errno.ENETRESET,  # "Network dropped connection on reset"
        errno.ENONET,  # "Machine is not on the network"
    ))
    
    def is_connection_err(exc):
        """Return True if an exception is connection-related."""
        if isinstance(exc, ConnectionError):
            # https://docs.python.org/3/library/exceptions.html#ConnectionError
            # ConnectionError includes:
            # * BrokenPipeError (EPIPE, ESHUTDOWN)
            # * ConnectionAbortedError (ECONNABORTED)
            # * ConnectionRefusedError (ECONNREFUSED)
            # * ConnectionResetError (ECONNRESET)
            return True
        if isinstance(exc, socket.gaierror):
            # failed DNS resolution on connect()
            return True
        if isinstance(exc, (socket.timeout, TimeoutError)):
            # timeout on connect(), recv(), send()
            return True
        if isinstance(exc, OSError):
            # ENOTCONN == "Transport endpoint is not connected"
            return (exc.errno in NETWORK_ERRNOS) or (exc.errno == errno.ENOTCONN)
        if isinstance(exc, ssl.SSLError):
            # Let's consider any SSL error a connection error. Usually this is:
            # * ssl.SSLZeroReturnError: "TLS/SSL connection has been closed"
            # * ssl.SSLError: [SSL: BAD_LENGTH] bad length
            return True
        return False