Skip to content

Conversation

@tboy1337
Copy link

Summary

This PR enhances exception handling in the HTTPAdapter class by preserving exception chains using Python's explicit from clause. This change improves debugging and error traceability by maintaining the original exception context when wrapping or converting urllib3 exceptions to requests-specific exceptions.

Changes Made

Core Changes (src/requests/adapters.py)

Modified 13 exception raise statements across two key methods:

  1. get_connection_with_tls_context() - Preserves chain when ValueError is converted to InvalidURL
  2. send() - Preserves chains for the following exception conversions:
    • LocationValueErrorInvalidURL
    • ProtocolError / OSErrorConnectionError
    • MaxRetryError (with various reasons) → ConnectTimeout, RetryError, ProxyError, SSLError, or ConnectionError
    • ClosedPoolErrorConnectionError
    • _ProxyErrorProxyError
    • _SSLErrorSSLError
    • ReadTimeoutErrorReadTimeout
    • _InvalidHeaderInvalidHeader

Testing (tests/test_adapters.py)

Added comprehensive test coverage with 14 new test methods in a dedicated TestExceptionChaining class:

  • Each test verifies that the __cause__ attribute is properly set when exceptions are raised
  • Tests cover all modified exception handling paths
  • Uses mocking to simulate various urllib3 exception scenarios
  • Ensures backward compatibility while improving error context

Benefits

  1. Better Debugging: Developers can trace the full exception chain to understand the root cause of errors
  2. Improved Error Context: The original exception details are preserved rather than being lost during conversion
  3. Python Best Practices: Follows PEP 3134 guidelines for explicit exception chaining
  4. No Breaking Changes: The change is purely additive and doesn't affect the public API or existing exception behavior

Testing

All new exception chaining behavior is covered by unit tests that verify:

  • The correct exception type is raised
  • The exception chain is preserved via the __cause__ attribute
  • All 14 exception conversion scenarios maintain proper chaining

Example

Before:

raise ConnectionError(err, request=request)

After:

raise ConnectionError(err, request=request) from err

When an error occurs, users will now see the full exception chain in tracebacks, making it easier to diagnose issues.

…ins using 'from' clause. Updated multiple error raises to maintain original exceptions for better debugging and traceability.
@tboy1337
Copy link
Author

tboy1337 commented Oct 22, 2025

I should add that this issue was found because of I think (I'm not 100% sure because everything was also typed according to mypy rules in the commit) pylint in #7054, if it was pylint that found this issue and it is a legitimate issue then it makes a strong case for the project to start using it imo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant