ConnectionError
The OSError branch for sockets and pipes. Four subclasses tell you what happened: nobody listening (refused), the peer hung up (reset / broken pipe), or the connection was dropped locally (aborted).
Demo
import errno codes = {'pipe': errno.EPIPE, 'aborted': errno.ECONNABORTED, 'refused': errno.ECONNREFUSED, 'reset': errno.ECONNRESET} e = OSError(codes['refused'], 'simulated') (type(e).__name__, isinstance(e, ConnectionError))
Trigger never names a subclass, yet every result is a specific one — errno picked it. The codes use the errno.NAME constants because the numbers differ by OS (ECONNREFUSED is 111 on Linux, 61 on macOS, 10061 on Windows). In Handle, timeout escapes the except ConnectionError clause: TimeoutError is a sibling, not a child.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| *args | object | no | A message, or (errno, strerror) like any OSError. Subclasses are usually raised by the socket layer, not constructed by hand. |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| errno | int | None | errno.EPIPE / ESHUTDOWN, ECONNABORTED, ECONNREFUSED or ECONNRESET when raised by the OS. Compare with the errno constants, not numbers. |
| strerror | str | None | OS text, e.g. 'Connection refused' on Linux; Windows uses its own wording ('No connection could be made because the target machine actively refused it'). |
| winerror | int | Windows only: 10061 (refused), 10054 (reset), 10053 (aborted) … |
Common patterns
import time for attempt in range(5): try: conn = connect() break except (ConnectionError, TimeoutError): if attempt == 4: raise time.sleep(2 ** attempt)
import os, sys try: for line in lines: print(line) sys.stdout.flush() except BrokenPipeError: devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) sys.exit(1)
try: conn.sendall(payload) except (BrokenPipeError, ConnectionResetError): log.info('client went away')
Examples
Pitfalls
try: raise ConnectionResetError('peer closed the connection') except ConnectionRefusedError: r = 'retry' r
try: raise ConnectionResetError('peer closed the connection') except ConnectionError: r = 'retry' r
def call(): raise TimeoutError('timed out') try: call() except ConnectionError: r = 'retry' r
def call(): raise TimeoutError('timed out') try: call() except (ConnectionError, TimeoutError): r = 'retry' r
When to use
- Retry logic around sockets, HTTP clients built on the stdlib, database drivers that surface OSErrors
- Handling clients that disconnect mid-request on a server
- Raising it from your own client code when the remote end misbehaves
- Timeouts → also catch TimeoutError
- requests / httpx → catch their own ConnectionError classes (not the built-in one)
- DNS failures → socket.gaierror (an OSError, not a ConnectionError)
Notes
FAQ
The target host answered, but nothing is listening on that port: the server is not running, listens on another port or interface (127.0.0.1 vs 0.0.0.0), or a firewall rejects the connection. Windows shows it as [WinError 10061] No connection could be made because the target machine actively refused it; macOS as [Errno 61].