Merge pull request #39 from matusf/29-add-raise_for_status

Add `raise_for_status()` to API
This commit is contained in:
Tom Christie 2019-05-08 10:07:26 +01:00 committed by GitHub
commit 5c1cb305bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 1 deletions

View File

@ -34,6 +34,12 @@ class PoolTimeout(Timeout):
# HTTP exceptions...
class HttpError(Exception):
"""
An Http error occurred.
"""
class ProtocolError(Exception):
"""
Malformed HTTP.

View File

@ -14,7 +14,13 @@ from .decoders import (
IdentityDecoder,
MultiDecoder,
)
from .exceptions import InvalidURL, ResponseClosed, ResponseNotRead, StreamConsumed
from .exceptions import (
HttpError,
InvalidURL,
ResponseClosed,
ResponseNotRead,
StreamConsumed,
)
from .utils import (
get_reason_phrase,
is_known_encoding,
@ -627,3 +633,22 @@ class Response:
def __repr__(self) -> str:
class_name = self.__class__.__name__
return f"<{class_name}(status_code={self.status_code})>"
def raise_for_status(self) -> None:
"""
Raise the `HttpError` if one occurred.
"""
message = (
"{0.status_code} {error_type}: {0.reason_phrase} for url: {0.url}\n"
"For more information check: https://httpstatuses.com/{0.status_code}"
)
if 400 <= self.status_code < 500:
message = message.format(self, error_type="Client Error")
elif 500 <= self.status_code < 600:
message = message.format(self, error_type="Server Error")
else:
message = ""
if message:
raise HttpError(message)

View File

@ -9,6 +9,8 @@ async def app(scope, receive, send):
assert scope["type"] == "http"
if scope["path"] == "/slow_response":
await slow_response(scope, receive, send)
elif scope["path"].startswith("/status"):
await status_code(scope, receive, send)
else:
await hello_world(scope, receive, send)
@ -36,6 +38,18 @@ async def slow_response(scope, receive, send):
await send({"type": "http.response.body", "body": b"Hello, world!"})
async def status_code(scope, receive, send):
status_code = int(scope["path"].replace("/status/", ""))
await send(
{
"type": "http.response.start",
"status": status_code,
"headers": [[b"content-type", b"text/plain"]],
}
)
await send({"type": "http.response.body", "body": b"Hello, world!"})
@pytest.fixture
async def server():
config = Config(app=app, lifespan="off")

View File

@ -50,3 +50,18 @@ async def test_stream_request(server):
"POST", "http://127.0.0.1:8000/", content=hello_world()
)
assert response.status_code == 200
@pytest.mark.asyncio
async def test_raise_for_status(server):
async with httpcore.Client() as client:
for status_code in (200, 400, 404, 500, 505):
response = await client.request(
"GET", f"http://127.0.0.1:8000/status/{status_code}"
)
if 400 <= status_code < 600:
with pytest.raises(httpcore.exceptions.HttpError):
response.raise_for_status()
else:
assert response.raise_for_status() is None