Preserve exception chain in morsel_to_cookie max-age conversion
Summary
This PR improves exception handling in the morsel_to_cookie function by preserving the original ValueError when a max-age conversion fails, following Python's exception chaining best practices.
Changes Made
-
Modified
src/requests/cookies.py:- Updated the exception handling in
morsel_to_cookie()to useraise ... from excsyntax - This preserves the original
ValueErroras the__cause__attribute when raising aTypeError
- Updated the exception handling in
-
Added test in
tests/test_requests.py:- New test
test_max_age_exception_chaining()to verify exception chaining behavior - Validates that the
TypeErroris raised with the correct message - Confirms the original
ValueErroris preserved in the exception chain - Verifies the ValueError message contains "invalid literal for int()"
- New test
Motivation
Previously, when an invalid max-age value was provided, the original ValueError from int() conversion was lost, making debugging more difficult. By using proper exception chaining (raise ... from exc), developers can now:
- See the complete exception traceback
- Understand both the high-level error (invalid max-age) and the low-level cause (ValueError from int conversion)
- Leverage Python's exception chaining features for better debugging and logging
Testing
The new test ensures that:
- The appropriate
TypeErroris still raised for invalid max-age values - The error message remains descriptive and helpful
- The original
ValueErroris accessible via the__cause__attribute - The complete exception chain is preserved for debugging purposes
Impact
-
No breaking changes - The external behavior remains the same (still raises
TypeError) - Better debugging - Developers get more context when errors occur
- Best practices - Follows PEP 3134 for explicit exception chaining
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 https://github.com/psf/requests/pull/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.