diff --git a/morpc/req.py b/morpc/req.py index 7ae745a..4fed0d0 100644 --- a/morpc/req.py +++ b/morpc/req.py @@ -51,8 +51,12 @@ def get_json_safely(url, params=None, headers=default_headers, session: Session else: json = r.json() else: - logger.error(f"Request failed. Content: {r.content}") - raise HTTPError(f"Request failed with status {r.status_code}: {r.url}") + # 204 means the request was valid but there is nothing to return, which callers may treat as no rows. + if r.status_code == 204: + logger.warning(f"No content returned: {r.url}") + else: + logger.error(f"Request failed. Content: {r.content}") + raise HTTPError(f"Request failed with status {r.status_code}: {r.url}", response=r) else: logger.debug(f"Request successful. Decoding return JSON.") try: diff --git a/tests/test_req.py b/tests/test_req.py index c21dbcd..8c43c41 100644 --- a/tests/test_req.py +++ b/tests/test_req.py @@ -32,5 +32,12 @@ def test_get_json_safely_raises_http_error_on_failed_request(): get_json_safely("http://example", session=_FakeSession(_Response(400))) +def test_get_json_safely_http_error_carries_response(): + # Callers can tell "no content" (204, e.g. a Census geography with no data for a year) from a failure. + with pytest.raises(HTTPError) as excinfo: + get_json_safely("http://example", session=_FakeSession(_Response(204))) + assert excinfo.value.response.status_code == 204 + + def test_get_json_safely_returns_json_on_success(): assert get_json_safely("http://example", session=_FakeSession(_Response(200, [["a"], ["1"]]))) == [["a"], ["1"]]