Skip to content

requests.HTTPError should include response object for compatibility with standard usage #750

@dvdhoekrst

Description

@dvdhoekrst

Hi KSM team,

While working with the Keeper Secrets Manager SDK, we encountered an issue where the SDK raises a requests.HTTPError without attaching the actual HTTP response object to the exception. This leads to downstream failures when consuming code attempts to inspect the .response attribute — for example, in logging or retry logic.


🧱 Problem in the SDK

In core.py, line 673:

raise requests.HTTPError(f"Status Code: {rs.status_code}{reason}{message}")

This raises an HTTPError without including the response object, leaving e.response as None.


⚠️ Why This Is Problematic

The requests.HTTPError exception is intended to wrap the actual HTTP response — even though response is optional in the constructor.

For example, the following pattern is common and expected:

raise requests.HTTPError("Something went wrong", response=response_obj)

Without the response parameter, client code relying on e.response.status_code, e.response.text, or e.response.headers will fail with AttributeError.


📚 Supporting Evidence from requests

1. Response.raise_for_status() usage

raise HTTPError(http_error_msg, response=self)

The library always includes the response object.

2. RequestException class definition

The core of the exception hierarchy documents the intent directly:

class RequestException(IOError):
    """There was an ambiguous exception that occurred while handling your
    request.
    """

    def __init__(self, *args, **kwargs):
        """Initialize RequestException with `request` and `response` objects."""
        response = kwargs.pop("response", None)
        self.response = response
        self.request = kwargs.pop("request", None)
        if response is not None and not self.request and hasattr(response, "request"):
            self.request = self.response.request
        super().__init__(*args, **kwargs)

This shows that requests is designed for the response object to be present and inspectable.


✅ Recommended Fix

Please change:

raise requests.HTTPError(f"Status Code: {rs.status_code}{reason}{message}")

to:

raise requests.HTTPError(f"Status Code: {rs.status_code}{reason}{message}", response=rs)

This will ensure better compatibility with logging systems, retry handlers, and any code using standard requests exception handling patterns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions