Common networking failures
- Timeouts: server too slow
- Connection errors: server down, wrong port
- DNS errors: domain name can’t be resolved
- HTTP errors: 4xx/5xx responses
requests exceptions
import requests
try:
r = requests.get("https://httpbin.org/delay/10", timeout=2)
r.raise_for_status()
print(r.text[:100])
except requests.Timeout:
print("Timed out")
except requests.ConnectionError:
print("Connection error")
except requests.HTTPError as e:
print("HTTP error:", e)
except requests.RequestException as e:
print("Other request error:", e)Add a timeout everywhere
- Always set
timeout= - Combine with retries if needed
Basic backoff idea
import time
import requests
url = "https://httpbin.org/status/503"
wait = 1
for attempt in range(4):
try:
r = requests.get(url, timeout=5)
r.raise_for_status()
print("success")
break
except requests.RequestException:
print("failed, sleeping", wait)
time.sleep(wait)
wait *= 2Tip
For production-grade retries, use a library or configure a session with retry adapters.
Why networks fail so often
A network call depends on many things you do not control: your Wi-Fi, a DNS server, the remote machine, and every router in between. Any of them can be slow or down at any moment. Code that assumes success will eventually hang or crash, so treat failure as a normal outcome and decide in advance what your program should do.
Reading the requests example
The requests library has one base error, requests.RequestException, and more specific ones below it. The try block asks for a page that deliberately takes 10 seconds, with timeout=2:
requests.Timeoutfires because the server did not answer in time.requests.ConnectionErrorcovers a server that is down, a wrong port, or a name that cannot be resolved (DNS).raise_for_status()turns a 4xx or 5xx response into arequests.HTTPError. Without it, a 404 or 503 is a "successful" call that returns an error page, and your program would carry on with bad data.- The final
RequestExceptioncatches everything else.
Order matters: put specific handlers first and the general one last.
Timeouts: the most important line
requests.get(url) has no timeout by default. A silent server can block your program forever. Always pass timeout=. A single number applies to connecting and to each wait for data; a tuple such as timeout=(3, 10) sets connect and read separately.
Retrying safely
The backoff example doubles its wait after each failure (1, 2, 4 seconds), so a struggling server gets breathing room. Only retry things that are safe to repeat, such as a GET. Retrying a payment POST could charge someone twice. Retry on timeouts, connection errors and 503, but not on 404 or 401, since asking again will not change the answer.
A small helper keeps this tidy:
import time
import requests
def fetch(url: str, attempts: int = 3) -> str | None:
wait = 1
for attempt in range(1, attempts + 1):
try:
r = requests.get(url, timeout=5)
r.raise_for_status()
return r.text
except requests.RequestException as e:
print(f"attempt {attempt} failed: {e}")
if attempt < attempts:
time.sleep(wait)
wait *= 2
return NoneIt returns None after the last failure, so the caller decides what to do next.
Common mistakes
- Calling
requests.getwithouttimeout. - Forgetting
raise_for_status()and treating an error page as data. - Catching a bare
except:and hiding the real problem. - Retrying forever with no delay, which hammers a server that is already struggling.
When to use it
Use these patterns for every call that leaves your machine. Log the failure clearly, retry a few times when it makes sense, and then give up with a helpful message.
🧪 Try It Yourself
Exercise 1 – GET Request
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – POST with JSON
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – Handle Timeout
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.