Catching Anomalies via requests.exceptions.ConnectionError

๐Ÿท๏ธ APIs and HTTP Requests / Timeouts and Error Handling


๐Ÿง  Context Introduction

When your Python script reaches out to an external API or web service, things don't always go smoothly. Network issues, server downtime, or firewall blocks can cause your connection to fail. The requests.exceptions.ConnectionError is a built-in exception in the requests library that catches these network-level failures. Understanding how to catch and handle this error helps you build resilient scripts that don't crash unexpectedly when the network misbehaves.


โš™๏ธ What is a ConnectionError?

A ConnectionError occurs when your Python script cannot establish a TCP connection to the target server. This is different from a timeout (where the connection starts but takes too long) or an HTTP error (where the server responds with a 4xx or 5xx status code).

Common scenarios that trigger a ConnectionError: - The server is offline or unreachable - A firewall is blocking the connection - The domain name does not resolve to an IP address - The port is closed on the target server - Network cables are unplugged or Wi-Fi is disconnected


๐Ÿ› ๏ธ How to Catch a ConnectionError

To catch this exception, you first import the requests library and then wrap your HTTP call inside a try-except block. The exception class is accessed as requests.exceptions.ConnectionError.

Basic structure: - Import the requests library at the top of your script - Place your requests.get() or requests.post() call inside a try block - Use except requests.exceptions.ConnectionError to catch the failure - Inside the except block, print a meaningful message or log the error

Example scenario: - You try to fetch data from https://api.example.com/status - If the server is down, the script prints "Unable to connect to the API server. Please check network connectivity." instead of crashing


๐Ÿ“Š Comparison: ConnectionError vs Other Exceptions

Exception Type When It Occurs Example Cause
ConnectionError Cannot establish TCP connection Server offline, firewall block
Timeout Connection established but no response within time limit Slow server, network congestion
HTTPError Server responds with error status code (4xx, 5xx) Invalid endpoint, authentication failure
RequestException Parent class for all requests exceptions Catch-all for any request failure

๐Ÿ•ต๏ธ Real-World Anomaly Detection Patterns

When monitoring infrastructure, catching ConnectionError helps you detect anomalies like:

  • Service outages: A critical API suddenly becomes unreachable
  • Network partitions: Internal services cannot communicate due to firewall changes
  • DNS failures: Domain resolution stops working after DNS configuration changes
  • Port changes: A service moves to a different port without updating your configuration

Detection workflow: - Wrap each external API call in a try-except block for ConnectionError - Log the error with a timestamp and the target URL - Increment a failure counter for that endpoint - Trigger an alert if failures exceed a threshold (e.g., 3 consecutive failures)


๐Ÿงช Best Practices for Handling ConnectionError

  • Always catch ConnectionError separately from other exceptions to handle network issues differently than application errors
  • Implement retry logic with exponential backoff โ€” wait 1 second, then 2 seconds, then 4 seconds before retrying
  • Log the full error details including the target URL and timestamp for debugging
  • Set a reasonable timeout using the timeout parameter in your request to avoid hanging indefinitely
  • Check network prerequisites before making the request, such as verifying DNS resolution with socket.gethostbyname()

Example retry strategy: - Attempt 1: Immediate retry after 1 second - Attempt 2: Retry after 2 seconds - Attempt 3: Retry after 4 seconds - After 3 failures: Log the error and exit gracefully


๐Ÿšจ Common Pitfalls to Avoid

  • Catching ConnectionError too broadly โ€” do not catch all exceptions with a bare except: clause
  • Ignoring the error silently โ€” always log or print the error for visibility
  • Not setting a timeout โ€” without a timeout, your script may hang forever waiting for a connection
  • Retrying immediately without delay โ€” this can overwhelm a struggling server or network
  • Assuming all connection failures are the same โ€” distinguish between DNS failures, refused connections, and network unreachable errors using the exception's args or response attribute

โœ… Summary

Catching requests.exceptions.ConnectionError is a fundamental skill for building robust Python scripts that interact with external services. By handling network failures gracefully, you prevent your scripts from crashing and gain visibility into infrastructure anomalies. Always combine this with proper logging, retry logic, and timeout settings to create production-ready code that can withstand real-world network conditions.


This exception is raised when a network connection cannot be established to the target server, allowing engineers to handle network failures gracefully.


๐Ÿงช Example 1: Basic ConnectionError catch with a fake URL

This example shows how to catch a connection error when the server does not exist.

import requests

try:
    response = requests.get("https://this-domain-does-not-exist-12345.com")
except requests.exceptions.ConnectionError:
    print("Connection failed โ€” server not reachable")

๐Ÿ“ค Output: Connection failed โ€” server not reachable


๐Ÿงช Example 2: Catching ConnectionError with a timeout

This example demonstrates that a timeout is a different exception, not a ConnectionError.

import requests

try:
    response = requests.get("https://httpbin.org/delay/10", timeout=2)
except requests.exceptions.ConnectionError:
    print("ConnectionError caught")
except requests.exceptions.Timeout:
    print("Timeout caught โ€” this is NOT a ConnectionError")

๐Ÿ“ค Output: Timeout caught โ€” this is NOT a ConnectionError


๐Ÿงช Example 3: Distinguishing between ConnectionError and other exceptions

This example shows how to handle ConnectionError separately from other request failures.

import requests

url = "https://httpbin.org/status/500"

try:
    response = requests.get(url)
    response.raise_for_status()
except requests.exceptions.ConnectionError:
    print("Could not connect to the server")
except requests.exceptions.HTTPError:
    print("Server responded with an error status code")

๐Ÿ“ค Output: Server responded with an error status code


๐Ÿงช Example 4: Retrying after a ConnectionError

This example shows a simple retry pattern when a connection fails temporarily.

import requests
import time

url = "https://httpbin.org/status/200"
max_retries = 3

for attempt in range(max_retries):
    try:
        response = requests.get(url, timeout=5)
        print("Success on attempt", attempt + 1)
        break
    except requests.exceptions.ConnectionError:
        print("Attempt", attempt + 1, "failed โ€” retrying in 2 seconds")
        time.sleep(2)
else:
    print("All retries exhausted โ€” connection still failing")

๐Ÿ“ค Output: Success on attempt 1


๐Ÿงช Example 5: Logging the full error details for debugging

This example shows how to capture and display the underlying error message from a ConnectionError.

import requests

try:
    response = requests.get("https://localhost:9999", timeout=3)
except requests.exceptions.ConnectionError as error:
    print("ConnectionError details:")
    print("  Type:", type(error).__name__)
    print("  Message:", str(error))

๐Ÿ“ค Output: ConnectionError details: / Type: ConnectionError / Message: HTTPConnectionPool(host='localhost', port=9999): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 61] Connection refused'))


Comparison Table

Scenario Exception Type Typical Cause
Server does not exist ConnectionError DNS resolution failure or unreachable host
Server refuses connection ConnectionError Port closed or service not running
Request takes too long Timeout Server slow or network congestion
Server returns error status HTTPError 4xx or 5xx response code
Invalid URL format InvalidURL Malformed URL string

๐Ÿง  Context Introduction

When your Python script reaches out to an external API or web service, things don't always go smoothly. Network issues, server downtime, or firewall blocks can cause your connection to fail. The requests.exceptions.ConnectionError is a built-in exception in the requests library that catches these network-level failures. Understanding how to catch and handle this error helps you build resilient scripts that don't crash unexpectedly when the network misbehaves.


โš™๏ธ What is a ConnectionError?

A ConnectionError occurs when your Python script cannot establish a TCP connection to the target server. This is different from a timeout (where the connection starts but takes too long) or an HTTP error (where the server responds with a 4xx or 5xx status code).

Common scenarios that trigger a ConnectionError: - The server is offline or unreachable - A firewall is blocking the connection - The domain name does not resolve to an IP address - The port is closed on the target server - Network cables are unplugged or Wi-Fi is disconnected


๐Ÿ› ๏ธ How to Catch a ConnectionError

To catch this exception, you first import the requests library and then wrap your HTTP call inside a try-except block. The exception class is accessed as requests.exceptions.ConnectionError.

Basic structure: - Import the requests library at the top of your script - Place your requests.get() or requests.post() call inside a try block - Use except requests.exceptions.ConnectionError to catch the failure - Inside the except block, print a meaningful message or log the error

Example scenario: - You try to fetch data from https://api.example.com/status - If the server is down, the script prints "Unable to connect to the API server. Please check network connectivity." instead of crashing


๐Ÿ“Š Comparison: ConnectionError vs Other Exceptions

Exception Type When It Occurs Example Cause
ConnectionError Cannot establish TCP connection Server offline, firewall block
Timeout Connection established but no response within time limit Slow server, network congestion
HTTPError Server responds with error status code (4xx, 5xx) Invalid endpoint, authentication failure
RequestException Parent class for all requests exceptions Catch-all for any request failure

๐Ÿ•ต๏ธ Real-World Anomaly Detection Patterns

When monitoring infrastructure, catching ConnectionError helps you detect anomalies like:

  • Service outages: A critical API suddenly becomes unreachable
  • Network partitions: Internal services cannot communicate due to firewall changes
  • DNS failures: Domain resolution stops working after DNS configuration changes
  • Port changes: A service moves to a different port without updating your configuration

Detection workflow: - Wrap each external API call in a try-except block for ConnectionError - Log the error with a timestamp and the target URL - Increment a failure counter for that endpoint - Trigger an alert if failures exceed a threshold (e.g., 3 consecutive failures)


๐Ÿงช Best Practices for Handling ConnectionError

  • Always catch ConnectionError separately from other exceptions to handle network issues differently than application errors
  • Implement retry logic with exponential backoff โ€” wait 1 second, then 2 seconds, then 4 seconds before retrying
  • Log the full error details including the target URL and timestamp for debugging
  • Set a reasonable timeout using the timeout parameter in your request to avoid hanging indefinitely
  • Check network prerequisites before making the request, such as verifying DNS resolution with socket.gethostbyname()

Example retry strategy: - Attempt 1: Immediate retry after 1 second - Attempt 2: Retry after 2 seconds - Attempt 3: Retry after 4 seconds - After 3 failures: Log the error and exit gracefully


๐Ÿšจ Common Pitfalls to Avoid

  • Catching ConnectionError too broadly โ€” do not catch all exceptions with a bare except: clause
  • Ignoring the error silently โ€” always log or print the error for visibility
  • Not setting a timeout โ€” without a timeout, your script may hang forever waiting for a connection
  • Retrying immediately without delay โ€” this can overwhelm a struggling server or network
  • Assuming all connection failures are the same โ€” distinguish between DNS failures, refused connections, and network unreachable errors using the exception's args or response attribute

โœ… Summary

Catching requests.exceptions.ConnectionError is a fundamental skill for building robust Python scripts that interact with external services. By handling network failures gracefully, you prevent your scripts from crashing and gain visibility into infrastructure anomalies. Always combine this with proper logging, retry logic, and timeout settings to create production-ready code that can withstand real-world network conditions.

Interactive Views

You are currently in ๐Ÿ“š All-in-One mode. Use the tabs at the top to switch to ๐Ÿ“– Theory Only or ๐Ÿ’ป Code Only views.

This exception is raised when a network connection cannot be established to the target server, allowing engineers to handle network failures gracefully.


๐Ÿงช Example 1: Basic ConnectionError catch with a fake URL

This example shows how to catch a connection error when the server does not exist.

import requests

try:
    response = requests.get("https://this-domain-does-not-exist-12345.com")
except requests.exceptions.ConnectionError:
    print("Connection failed โ€” server not reachable")

๐Ÿ“ค Output: Connection failed โ€” server not reachable


๐Ÿงช Example 2: Catching ConnectionError with a timeout

This example demonstrates that a timeout is a different exception, not a ConnectionError.

import requests

try:
    response = requests.get("https://httpbin.org/delay/10", timeout=2)
except requests.exceptions.ConnectionError:
    print("ConnectionError caught")
except requests.exceptions.Timeout:
    print("Timeout caught โ€” this is NOT a ConnectionError")

๐Ÿ“ค Output: Timeout caught โ€” this is NOT a ConnectionError


๐Ÿงช Example 3: Distinguishing between ConnectionError and other exceptions

This example shows how to handle ConnectionError separately from other request failures.

import requests

url = "https://httpbin.org/status/500"

try:
    response = requests.get(url)
    response.raise_for_status()
except requests.exceptions.ConnectionError:
    print("Could not connect to the server")
except requests.exceptions.HTTPError:
    print("Server responded with an error status code")

๐Ÿ“ค Output: Server responded with an error status code


๐Ÿงช Example 4: Retrying after a ConnectionError

This example shows a simple retry pattern when a connection fails temporarily.

import requests
import time

url = "https://httpbin.org/status/200"
max_retries = 3

for attempt in range(max_retries):
    try:
        response = requests.get(url, timeout=5)
        print("Success on attempt", attempt + 1)
        break
    except requests.exceptions.ConnectionError:
        print("Attempt", attempt + 1, "failed โ€” retrying in 2 seconds")
        time.sleep(2)
else:
    print("All retries exhausted โ€” connection still failing")

๐Ÿ“ค Output: Success on attempt 1


๐Ÿงช Example 5: Logging the full error details for debugging

This example shows how to capture and display the underlying error message from a ConnectionError.

import requests

try:
    response = requests.get("https://localhost:9999", timeout=3)
except requests.exceptions.ConnectionError as error:
    print("ConnectionError details:")
    print("  Type:", type(error).__name__)
    print("  Message:", str(error))

๐Ÿ“ค Output: ConnectionError details: / Type: ConnectionError / Message: HTTPConnectionPool(host='localhost', port=9999): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 61] Connection refused'))


Comparison Table

Scenario Exception Type Typical Cause
Server does not exist ConnectionError DNS resolution failure or unreachable host
Server refuses connection ConnectionError Port closed or service not running
Request takes too long Timeout Server slow or network congestion
Server returns error status HTTPError 4xx or 5xx response code
Invalid URL format InvalidURL Malformed URL string