{"id":"f467b0ae3936e13b","repo":"redis/redis-py","slug":"exc","errorCode":null,"errorMessage":"{exc}","messagePattern":"\\{exc\\}","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":878,"sourceCode":"                error_type=e,\n                retry_attempts=actual_retry_attempts,\n                is_internal=False,\n            )\n            raise e\n        except OSError as e:\n            e = ConnectionError(self._error_message(e))\n            await record_error_count(\n                server_address=getattr(self, \"host\", None),\n                server_port=getattr(self, \"port\", None),\n                network_peer_address=getattr(self, \"host\", None),\n                network_peer_port=getattr(self, \"port\", None),\n                error_type=e,\n                retry_attempts=actual_retry_attempts,\n                is_internal=False,\n            )\n            raise e\n        except Exception as exc:\n            raise ConnectionError(exc) from exc\n\n        try:\n            if not self.redis_connect_func:\n                # Use the default on_connect function\n                await self.on_connect_check_health(check_health=check_health)\n            else:\n                # Use the passed function redis_connect_func\n                (\n                    await self.redis_connect_func(self)\n                    if asyncio.iscoroutinefunction(self.redis_connect_func)\n                    else self.redis_connect_func(self)\n                )\n        except RedisError:\n            # clean up after any error in on_connect\n            await self.disconnect()\n            raise\n\n        # run any user callbacks. right now the only internal callback","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L860-L896","documentation":"Catch-all in AbstractConnection.connect: any unexpected exception during socket connect/dispatch that is not already a RedisError, timeout, or OSError is re-raised as ConnectionError(exc) from exc. The message is the str() of the underlying exception, so the real cause is preserved in __cause__ and in the message text.","triggerScenarios":"Any non-OSError, non-RedisError failure during connect()/on_connect — e.g. SSL errors, gaierror subclasses not caught earlier, unexpected parser failures, asyncio stream errors, etc.","commonSituations":"TLS/SNI misconfiguration; DNS failures that surface as a non-OSError; custom redis_connect_func raising; parser/encoder issues during handshake; asyncio loop closures.","solutions":["Read __cause__ (or the message text) to identify the wrapped exception and address THAT specifically.","For SSL/TLS issues, verify ssl_ca_certs / ssl_cert_reqs / ssl_check_hostname against your server.","For DNS/connectivity, verify host/port reachability and that the event loop is running.","If using redis_connect_func, ensure it does not raise on success and surfaces clear errors on failure."],"exampleFix":"// before\ntry:\n    await client.ping()\nexcept ConnectionError as e:\n    print(e)  # opaque wrapped message\n// after\ntry:\n    await client.ping()\nexcept ConnectionError as e:\n    logging.exception('connect failed: %s', e.__cause__)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError\ntry:\n    await client.ping()\nexcept ConnectionError as e:\n    logger.error('connect failed, underlying cause: %r', e.__cause__)\n    # branch on isinstance(e.__cause__, ssl.SSLError | OSError | ...)","preventionTips":["Always inspect __cause__ on this wrapped error.","Validate TLS settings and host reachability before relying on the connection."],"tags":["connection","connect","ssl","wrapper","diagnostics"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}