Skip to content

Commit 90f350b

Browse files
committed
fix: preserve text/plain error body in raise_if_error() after stream is consumed
1 parent b5b6f50 commit 90f350b

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

CHANGES.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
Enhancements and Fixes
55
----------------------
66

7+
- Preserve text/plain error body in raise_if_error() after stream is consumed. [#736]
8+
79
- Provide an API for SoftId-compliant management of the 'User-Agent'
8-
header [#719]
10+
header. [#719]
911

1012
- The ``astropy.samp`` module has been relocated and is now accessible under
11-
``pyvo.samp`` [#729]
13+
``pyvo.samp``. [#729]
1214

1315

1416
Deprecations and Removals

pyvo/dal/query.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ def execute_stream(self, *, post=False):
211211
try:
212212
response.raise_for_status()
213213
except requests.RequestException as ex:
214-
# save for later use
214+
# Cache the response body before returning the raw stream. If the
215+
# caller consumes the stream before calling raise_if_error()
216+
# this would lead to an empty error message
217+
_ = response.content
215218
self._ex = ex
216219

217220
return response.raw

pyvo/dal/tests/test_query.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def register_mocks(mocker):
9393
'GET', '//example.com/query/errornous',
9494
text='Error', status_code=500
9595
)),
96+
stack.enter_context(mocker.register_uri(
97+
'GET', 'http://example.com/query/plaintext_error',
98+
content=b'No intersection between cutout and image',
99+
headers={'Content-Type': 'text/plain; charset=utf-8'},
100+
status_code=500
101+
)),
96102
stack.enter_context(mocker.register_uri(
97103
'GET', 'http://example.com/query/errorstatus',
98104
content=get_pkg_data_contents('data/query/errorstatus.xml')
@@ -225,6 +231,14 @@ def test_http_exception_500(self):
225231
else:
226232
assert False
227233

234+
def test_http_exception_message_preserved(self):
235+
query = DALQuery('http://example.com/query/plaintext_error')
236+
stream = query.execute_stream()
237+
stream.read()
238+
with pytest.raises(DALServiceError) as exc_info:
239+
query.raise_if_error()
240+
assert 'No intersection between cutout and image' in str(exc_info.value)
241+
228242
def test_query_exception(self):
229243
service = DALService('http://example.com/query/errorstatus')
230244

0 commit comments

Comments
 (0)