Problem
HttpResponseError.body_snapshot documents itself as side-effect-free: it "never drains a single-use stream" and returns bytes "only when the body has already been captured for repeatable reads (a LoggableResponseBody)". That is not quite what the code does. For a LoggableResponseBody that has not yet been read, snapshot() calls self._drain() on first access, which reads the wrapped inner body — potentially blocking on network I/O. The outcome is still safe (the bytes are cached and reads stay repeatable), but capture happens lazily at snapshot time, not "already". A caller trusting the docstring may call body_snapshot() from a logging or post-mortem path believing it cannot touch the network, when the first call can.
Where
packages/dexpace-sdk-core/src/dexpace/sdk/core/errors/http.py:115-119 (docstring):
Safe to call from logging and post-mortem paths: it never drains a
single-use stream. Bytes are only returned when the body has already
been captured for repeatable reads (a ``LoggableResponseBody``); ...
packages/dexpace-sdk-core/src/dexpace/sdk/core/http/response/loggable_response_body.py:108 — snapshot() drains unconditionally:
self._drain()
if max_bytes is None:
return self._cached
Impact
Documentation accuracy only — no data is lost or corrupted. The risk is a caller relying on "never drains" / "already captured" and being surprised by a synchronous read on the first body_snapshot() over a not-yet-read LoggableResponseBody.
Suggested fix
Reword the docstring to say that for a LoggableResponseBody the snapshot drains-and-caches the inner body on first access (the read is repeatable afterward but may incur I/O the first time), while for any other body type it returns b"" without touching the payload. Drop the absolute "never drains" phrasing, or scope it explicitly to non-Loggable bodies.
Problem
HttpResponseError.body_snapshotdocuments itself as side-effect-free: it "never drains a single-use stream" and returns bytes "only when the body has already been captured for repeatable reads (aLoggableResponseBody)". That is not quite what the code does. For aLoggableResponseBodythat has not yet been read,snapshot()callsself._drain()on first access, which reads the wrapped inner body — potentially blocking on network I/O. The outcome is still safe (the bytes are cached and reads stay repeatable), but capture happens lazily at snapshot time, not "already". A caller trusting the docstring may callbody_snapshot()from a logging or post-mortem path believing it cannot touch the network, when the first call can.Where
packages/dexpace-sdk-core/src/dexpace/sdk/core/errors/http.py:115-119(docstring):packages/dexpace-sdk-core/src/dexpace/sdk/core/http/response/loggable_response_body.py:108—snapshot()drains unconditionally:Impact
Documentation accuracy only — no data is lost or corrupted. The risk is a caller relying on "never drains" / "already captured" and being surprised by a synchronous read on the first
body_snapshot()over a not-yet-readLoggableResponseBody.Suggested fix
Reword the docstring to say that for a
LoggableResponseBodythe snapshot drains-and-caches the inner body on first access (the read is repeatable afterward but may incur I/O the first time), while for any other body type it returnsb""without touching the payload. Drop the absolute "never drains" phrasing, or scope it explicitly to non-Loggablebodies.