HTTP library with thread-safe connection pooling, file post support, user friendly interface, and more.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive exception hierarchy for handling various HTTP and network errors. urllib3 provides specific exceptions for different failure scenarios, enabling precise error handling and robust application design.
Foundation exceptions that all other urllib3 exceptions inherit from.
class HTTPError(Exception):
"""Base exception used by urllib3."""
class HTTPWarning(Warning):
"""Base warning used by urllib3."""Exceptions related to connection pool management and state.
class PoolError(HTTPError):
"""Base exception for errors caused within a pool."""
def __init__(self, pool, message: str):
"""
Parameters:
- pool: The connection pool where error occurred
- message: Error description
"""
class EmptyPoolError(PoolError):
"""Pool has no available connections."""
class FullPoolError(PoolError):
"""Pool is full and cannot accept new connections."""
class ClosedPoolError(PoolError):
"""Pool has been closed and cannot be used."""Exceptions related to HTTP request and response processing.
class RequestError(PoolError):
"""Base exception for request-related errors with URLs."""
def __init__(self, pool, url: str, message: str):
"""
Parameters:
- pool: Connection pool
- url: Request URL where error occurred
- message: Error description
"""
class MaxRetryError(RequestError):
"""Maximum number of retries exceeded."""
def __init__(self, pool, url: str, reason=None):
"""
Parameters:
- pool: Connection pool
- url: Request URL
- reason: Underlying exception that caused max retries
"""
class HostChangedError(RequestError):
"""Request made to different host than expected."""
class ResponseError(RequestError):
"""Too many error responses from server."""
class DecodeError(HTTPError):
"""Automatic content decoding failed."""
class ProtocolError(HTTPError):
"""Protocol-level error during request/response."""
# Backwards compatibility alias
ConnectionError = ProtocolError
class ResponseNotChunked(ProtocolError):
"""Response not chunked when chunked encoding expected."""
class BodyNotHttplibCompatible(HTTPError):
"""Request body not compatible with httplib."""
class IncompleteRead(HTTPError):
"""Response shorter than expected Content-Length."""
def __init__(self, partial: bytes, expected: int):
"""
Parameters:
- partial: Data received before connection closed
- expected: Expected number of bytes
"""
class InvalidChunkLength(HTTPError):
"""Invalid chunk length in chunked transfer encoding."""
class InvalidHeader(HTTPError):
"""Invalid header name or value format."""
class UnrewindableBodyError(HTTPError):
"""Cannot rewind request body for retry."""Exceptions related to request timeouts and timing issues.
class TimeoutError(HTTPError):
"""Base timeout error."""
class TimeoutStateError(TimeoutError):
"""Invalid timeout state or configuration."""
class ReadTimeoutError(TimeoutError, RequestError):
"""Timeout while reading response data."""
class ConnectTimeoutError(TimeoutError, RequestError):
"""Timeout while establishing connection."""Exceptions related to network connections and connectivity.
class NewConnectionError(ConnectTimeoutError, PoolError):
"""Failed to establish new connection."""
class NameResolutionError(NewConnectionError):
"""DNS name resolution failed."""Exceptions related to SSL/TLS certificate validation and secure connections.
class SSLError(HTTPError):
"""SSL certificate or connection error."""
class CertificateError(SSLError):
"""SSL certificate validation error."""Exceptions related to proxy server connections and configuration.
class ProxyError(HTTPError):
"""Proxy connection error."""
def __init__(self, message: str, error: Exception):
"""
Parameters:
- message: Error description
- error: Original underlying error
"""
class ProxySchemeUnknown(AssertionError, ValueError):
"""Unknown proxy scheme in proxy URL."""
class ProxySchemeUnsupported(ValueError):
"""Unsupported proxy scheme."""Exceptions related to URL parsing and validation.
class LocationValueError(ValueError, HTTPError):
"""Invalid URL input or host specification."""
class LocationParseError(LocationValueError):
"""Failed to parse URL components."""
class URLSchemeUnknown(LocationValueError):
"""Unknown URL scheme."""
class HeaderParsingError(HTTPError):
"""Failed to parse HTTP headers."""Warning categories for non-fatal issues that should be brought to attention.
class SecurityWarning(HTTPWarning):
"""Security-related warnings (unverified HTTPS, weak SSL, etc.)."""
class InsecureRequestWarning(SecurityWarning):
"""Unverified HTTPS request warning."""
class NotOpenSSLWarning(SecurityWarning):
"""Non-OpenSSL SSL library in use warning."""
class SystemTimeWarning(SecurityWarning):
"""System time appears incorrect warning."""
class InsecurePlatformWarning(SecurityWarning):
"""Platform missing SSL/TLS security features warning."""
class DependencyWarning(HTTPWarning):
"""Missing optional dependencies warning."""import urllib3
http = urllib3.PoolManager()
try:
resp = http.request('GET', 'https://nonexistent.example.com')
except urllib3.exceptions.NewConnectionError as e:
print(f"Connection failed: {e}")
except urllib3.exceptions.TimeoutError as e:
print(f"Request timed out: {e}")
except urllib3.exceptions.HTTPError as e:
print(f"HTTP error: {e}")import urllib3
http = urllib3.PoolManager(retries=urllib3.Retry(total=3))
try:
resp = http.request('GET', 'https://httpbin.org/status/500')
except urllib3.exceptions.MaxRetryError as e:
print(f"Max retries exceeded: {e}")
print(f"Original error: {e.reason}")
print(f"Failed URL: {e.url}")import urllib3
# Disable SSL warnings for this example
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
http = urllib3.PoolManager()
try:
# This will raise an SSL error due to certificate issues
resp = http.request('GET', 'https://self-signed.badssl.com/')
except urllib3.exceptions.SSLError as e:
print(f"SSL error: {e}")
except urllib3.exceptions.CertificateError as e:
print(f"Certificate error: {e}")import urllib3
http = urllib3.PoolManager(timeout=urllib3.Timeout(total=1.0))
try:
# This will timeout
resp = http.request('GET', 'https://httpbin.org/delay/5')
except urllib3.exceptions.ConnectTimeoutError as e:
print(f"Connection timeout: {e}")
except urllib3.exceptions.ReadTimeoutError as e:
print(f"Read timeout: {e}")
except urllib3.exceptions.TimeoutError as e:
print(f"General timeout: {e}")import urllib3
# Create pool with limited connections
pool = urllib3.HTTPConnectionPool('httpbin.org', maxsize=1, block=False)
try:
# First request will succeed
resp1 = pool.urlopen('GET', '/delay/1', preload_content=False)
# Second request will fail because pool is full and block=False
resp2 = pool.urlopen('GET', '/delay/1')
except urllib3.exceptions.FullPoolError as e:
print(f"Pool is full: {e}")
finally:
pool.close()import urllib3
try:
# Invalid proxy URL
proxy = urllib3.ProxyManager('invalid://proxy.example.com')
except urllib3.exceptions.ProxySchemeUnknown as e:
print(f"Unknown proxy scheme: {e}")
try:
# Valid proxy but connection fails
proxy = urllib3.ProxyManager('http://nonexistent-proxy.example.com:8080')
resp = proxy.request('GET', 'https://httpbin.org/get')
except urllib3.exceptions.ProxyError as e:
print(f"Proxy error: {e}")
print(f"Original error: {e.original_error}")import urllib3
def make_request(url, retries=3, timeout=10):
"""Make HTTP request with comprehensive error handling."""
http = urllib3.PoolManager(
retries=urllib3.Retry(total=retries),
timeout=urllib3.Timeout(total=timeout)
)
try:
resp = http.request('GET', url)
return resp.status, resp.data
except urllib3.exceptions.MaxRetryError as e:
if isinstance(e.reason, urllib3.exceptions.NewConnectionError):
return None, f"Connection failed: {e.reason}"
elif isinstance(e.reason, urllib3.exceptions.TimeoutError):
return None, f"Request timed out: {e.reason}"
else:
return None, f"Max retries exceeded: {e.reason}"
except urllib3.exceptions.SSLError as e:
return None, f"SSL/TLS error: {e}"
except urllib3.exceptions.LocationValueError as e:
return None, f"Invalid URL: {e}"
except urllib3.exceptions.HTTPError as e:
return None, f"HTTP error: {e}"
except Exception as e:
return None, f"Unexpected error: {e}"
# Usage
status, result = make_request('https://httpbin.org/get')
if status:
print(f"Success: {status}")
else:
print(f"Error: {result}")import urllib3
import json
def get_json_data(url):
"""Get JSON data with comprehensive error handling."""
http = urllib3.PoolManager()
try:
resp = http.request('GET', url)
if resp.status != 200:
raise urllib3.exceptions.HTTPError(f"HTTP {resp.status}: {resp.reason}")
try:
return resp.json()
except (json.JSONDecodeError, UnicodeDecodeError) as e:
raise urllib3.exceptions.DecodeError(f"Failed to decode JSON: {e}")
except urllib3.exceptions.DecodeError:
raise # Re-raise decode errors
except urllib3.exceptions.HTTPError:
raise # Re-raise HTTP errors
except Exception as e:
raise urllib3.exceptions.HTTPError(f"Unexpected error: {e}")
# Usage with error handling
try:
data = get_json_data('https://jsonplaceholder.typicode.com/posts/1')
print(f"Title: {data.get('title')}")
except urllib3.exceptions.DecodeError as e:
print(f"JSON decode error: {e}")
except urllib3.exceptions.HTTPError as e:
print(f"HTTP error: {e}")import urllib3
import warnings
# Disable specific warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Or disable all urllib3 warnings
urllib3.disable_warnings()
# Custom warning handling
def custom_warning_handler(message, category, filename, lineno, file=None, line=None):
if category == urllib3.exceptions.InsecureRequestWarning:
print(f"Security warning: {message}")
else:
print(f"Other warning: {message}")
# Set custom warning handler
warnings.showwarning = custom_warning_handler
# Make request that would normally generate warning
http = urllib3.PoolManager()
resp = http.request('GET', 'https://self-signed.badssl.com/', verify=False)The urllib3 exception hierarchy allows for precise error handling:
Exception
├── HTTPError (base for all urllib3 errors)
│ ├── PoolError
│ │ ├── EmptyPoolError
│ │ ├── FullPoolError
│ │ ├── ClosedPoolError
│ │ └── RequestError
│ │ ├── MaxRetryError
│ │ ├── HostChangedError
│ │ └── ResponseError
│ ├── TimeoutError
│ │ ├── TimeoutStateError
│ │ ├── ReadTimeoutError
│ │ └── ConnectTimeoutError
│ ├── SSLError
│ │ └── CertificateError
│ ├── ProxyError
│ ├── DecodeError
│ ├── ProtocolError (ConnectionError)
│ ├── LocationValueError
│ │ ├── LocationParseError
│ │ └── URLSchemeUnknown
│ └── Various other specific errors...
│
└── Warning
└── HTTPWarning
├── SecurityWarning
│ ├── InsecureRequestWarning
│ ├── NotOpenSSLWarning
│ ├── SystemTimeWarning
│ └── InsecurePlatformWarning
└── DependencyWarningThis hierarchy allows catching errors at different levels of specificity based on your application's needs.
Install with Tessl CLI
npx tessl i tessl/pypi-urllib3