TimeoutError — Operation Timed Out Fix
A TimeoutError is raised when a socket operation or other I/O operation exceeds its configured timeout period. It’s a subclass of OSError. This is different from asyncio.TimeoutError, which is used in async contexts.
Description
TimeoutError occurs when you set a timeout on a socket or other blocking operation and the operation doesn’t complete within the specified time. The timeout is set using socket.settimeout() or passed as a parameter to functions like socket.create_connection().
Note: In Python 3.3+, socket.timeout is an alias for TimeoutError. In async contexts, asyncio.TimeoutError is a separate exception raised by asyncio.wait_for().
Common scenarios:
- Socket connection timeout — server takes too long to respond.
- Socket read timeout — data doesn’t arrive within time limit.
- Socket write timeout — send buffer is full and write blocks.
- DNS resolution timeout — hostname lookup takes too long.
- HTTP request timeout — server doesn’t respond in time.
Common Causes
import socket
# Cause 1: Connection timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1.0) # 1 second timeout
sock.connect(("192.168.1.999", 80)) # TimeoutError: connection too slow
# Cause 2: Read timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("example.com", 80))
sock.settimeout(1.0)
data = sock.recv(1024) # TimeoutError if no data in 1 second
# Cause 3: Write timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1.0)
sock.connect(("example.com", 80))
sock.send(b"x" * 10**8) # TimeoutError if send buffer full
# Cause 4: Using socket.create_connection with timeout
sock = socket.create_connection(("example.com", 80), timeout=2.0)
# TimeoutError if connection takes more than 2 seconds
# Cause 5: HTTP request timeout
import requests
response = requests.get("http://slow-server.com", timeout=1.0) # TimeoutError
Solutions
Fix 1: Set appropriate timeouts
import socket
# Wrong — no timeout, may hang forever
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("example.com", 80))
data = sock.recv(4096)
# Correct — set reasonable timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10.0) # 10 seconds
try:
sock.connect(("example.com", 80))
data = sock.recv(4096)
except socket.timeout:
print("Operation timed out")
Fix 2: Handle TimeoutError with retry logic
import socket
import time
# Wrong — single attempt
sock = socket.create_connection(("example.com", 80), timeout=5)
# Correct — retry with backoff
def connect_with_retry(host, port, timeout=5, max_retries=3):
for attempt in range(max_retries):
try:
return socket.create_connection((host, port), timeout=timeout)
except socket.timeout:
wait = 2 ** attempt
print(f"Attempt {attempt + 1} timed out, retrying in {wait}s...")
time.sleep(wait)
raise socket.timeout(f"Failed to connect to {host}:{port}")
sock = connect_with_retry("example.com", 80)
Fix 3: Use requests with timeout for HTTP
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# Wrong — no timeout
response = requests.get("http://api.example.com/data")
# Correct — timeout with retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)
try:
response = session.get("http://api.example.com/data", timeout=(3.05, 30))
data = response.json()
except requests.Timeout:
print("Request timed out")
Fix 4: Use asyncio for async timeouts
import asyncio
# Wrong — no timeout in async context
async def fetch_data():
reader, writer = await asyncio.open_connection("example.com", 80)
data = await reader.read(1024) # May hang
# Correct — use asyncio.wait_for
async def fetch_data():
try:
reader, writer = await asyncio.wait_for(
asyncio.open_connection("example.com", 80),
timeout=10.0
)
data = await reader.read(1024)
return data
except asyncio.TimeoutError:
print("Async operation timed out")
return None
Fix 5: Use non-blocking I/O with select for timeout control
import socket
import select
# Wrong — blocking with fixed timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
sock.connect(("example.com", 80))
# Correct — use select for flexible timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("example.com", 80))
ready, _, _ = select.select([sock], [], [], 5.0)
if ready:
data = sock.recv(1024)
else:
print("Read timed out")
Related Errors
- BlockingIOError — non-blocking I/O would block.
- ConnectionError — network connection failed.
- OSError — generic OS-level error.
Comments