Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/requests/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
InvalidURL,
ProxyError,
ReadTimeout,
RequestException,
RetryError,
SSLError,
)
Expand Down Expand Up @@ -682,15 +683,15 @@ def send(
except _ProxyError as e:
raise ProxyError(e)

except (_SSLError, _HTTPError) as e:
if isinstance(e, _SSLError):
except (_SSLError, _HTTPError) as err:
if isinstance(err, _SSLError):
# This branch is for urllib3 versions earlier than v1.22
raise SSLError(e, request=request)
elif isinstance(e, ReadTimeoutError):
raise ReadTimeout(e, request=request)
elif isinstance(e, _InvalidHeader):
raise InvalidHeader(e, request=request)
raise SSLError(err, request=request) from err
elif isinstance(err, ReadTimeoutError):
raise ReadTimeout(err, request=request) from err
elif isinstance(err, _InvalidHeader):
raise InvalidHeader(err, request=request) from err
else:
raise
raise RequestException(err, request=request) from err

return self.build_response(request, resp)
37 changes: 37 additions & 0 deletions tests/test_adapters.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
from unittest import mock

import pytest
from urllib3.exceptions import HTTPError as _HTTPError

import requests.adapters
from requests.exceptions import RequestException


def test_request_url_trims_leading_path_separators():
"""See also https://github.com/psf/requests/issues/6643."""
a = requests.adapters.HTTPAdapter()
p = requests.Request(method="GET", url="http://127.0.0.1:10000//v:h").prepare()
assert "/v:h" == a.request_url(p, {})


def test_unknown_httperror_wrapped_in_requestexception():
"""Test that unknown urllib3 HTTPError types are wrapped in RequestException.

When urllib3 raises an HTTPError that isn't explicitly
handled (not SSLError, ReadTimeoutError, or InvalidHeader), it should be
wrapped in RequestException rather than propagating as-is.
"""
adapter = requests.adapters.HTTPAdapter()
request = requests.Request(method="GET", url="http://example.com").prepare()

# Create a generic HTTPError that doesn't match any specific handled types
generic_http_error = _HTTPError("Unknown HTTP error from urllib3")

# Mock the connection to raise our generic HTTPError
with mock.patch.object(
adapter, 'get_connection_with_tls_context'
) as mock_get_conn:
mock_conn = mock.MagicMock()
mock_conn.urlopen.side_effect = generic_http_error
mock_get_conn.return_value = mock_conn

# The exception should be catchable as RequestException
with pytest.raises(RequestException) as exc_info:
adapter.send(request)

# Verify it wraps the original error
assert exc_info.value.request == request
# Verify exception chaining
assert exc_info.value.__cause__ == generic_http_error