Skip to content

Requests - Working with Errors

This chapter discusses how to gracefully handle errors when working with the Requests library. Robust error management is crucial for building reliable applications.

The requests library has a base exception class requests.exceptions.RequestException from which most other exceptions inherit. Here are some common ones you’ll encounter:

requests.exceptions.ConnectionError: Raised for network problems (e.g., DNS failure, refused connection).

requests.exceptions.HTTPError: Raised by response.raise_for_status() for unsuccessful status codes (4xx client errors or 5xx server errors).

requests.exceptions.Timeout: Base class for timeout-related errors.

requests.exceptions.ConnectTimeout: Raised when a connection timeout occurs while trying to connect to the remote server.

requests.exceptions.ReadTimeout: Raised if the server does not send any data within the specified timeout period.

requests.exceptions.TooManyRedirects: Raised if a request exceeds the configured number of maximum redirections.

requests.exceptions.JSONDecodeError: Raised by response.json() if the response content cannot be decoded as JSON. This is technically from json.JSONDecodeError but commonly encountered when using response.json().

The standard Python try-except block is the best way to handle these exceptions.

Example: Handling Timeouts and HTTP Errors

Section titled “Example: Handling Timeouts and HTTP Errors”

This example demonstrates how to catch ConnectTimeout and HTTPError exceptions. The timeout parameter in requests.get() can be a single float for both connect and read timeouts, or a tuple (connect_timeout, read_timeout).

import requests
try:
# Using a very short timeout to deliberately cause a ConnectTimeout
# Using a URL that might return an error for HTTPError demonstration (e.g., if it required auth)
response = requests.get('https://jsonplaceholder.typicode.com/users', timeout=(0.001, 5)) # (connect_timeout, read_timeout)
# Check for HTTP errors (4xx or 5xx status codes)
response.raise_for_status() # This will raise an HTTPError if the response was an HTTP error
print("Request successful!")
# print(response.json()) # Process the response if successful
except requests.exceptions.ConnectTimeout as e:
print(f"Connection Timeout Error: {e}")
except requests.exceptions.ReadTimeout as e:
print(f"Read Timeout Error: {e}")
except requests.exceptions.HTTPError as e:
print(f"HTTP Error: {e}")
except requests.exceptions.RequestException as e: # Catch any other RequestException
print(f"An error occurred: {e}")
Connection Timeout Error: HTTPSConnectionPool(host='jsonplaceholder.typicode.com', port=443): Max retries exceeded with url: /users (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x...>, 'Connection to jsonplaceholder.typicode.com timed out. (connect timeout=0.001)'))

Note: The exact error message and object addresses (like 0x...) might vary slightly depending on your environment and the requests library version.

Using response.raise_for_status() is a convenient way to ensure your program reacts to bad HTTP responses. Always wrap your requests in try-except blocks to handle potential issues gracefully.