Skip to content

Commit

Permalink
HttpSession: Improve error message when someone forgot to pass catch_…
Browse files Browse the repository at this point in the history
…response=True + small optimization (#2762)

* Dont create fake new Request object to attach to LocustResponse, use the one from the exception instead

* Various type hint fixes in LocustResponse/HttpSession

* Dont fail on "... takes 1 positional argument but 2 were given" when trying to give descriptive error message when .failure/.success is called without a catch_response=True

* avoid mypy error "Signature of "request" incompatible with supertype "Session"  [override]"

* another place where mypy doesnt understand typing but pylance does...

* Rename "missing catch_response=True"-methods. further clarify error message.

* ignore type in one place

* remove unused imports

---------

Co-authored-by: Lars Holmberg <[email protected]>
  • Loading branch information
cyberw and Lars Holmberg authored Jun 25, 2024
1 parent e253453 commit 1a22015
Showing 1 changed file with 14 additions and 18 deletions.
32 changes: 14 additions & 18 deletions locust/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from urllib.parse import urlparse, urlunparse

import requests
from requests import Request, Response
from requests import Response
from requests.adapters import HTTPAdapter
from requests.auth import HTTPBasicAuth
from requests.exceptions import InvalidSchema, InvalidURL, MissingSchema, RequestException
Expand Down Expand Up @@ -54,8 +54,10 @@ class RESTKwargs(RequestKwargs, total=False):


class LocustResponse(Response):
def raise_for_status(self):
if hasattr(self, "error") and self.error:
error: Exception | None = None

def raise_for_status(self) -> None:
if self.error:
raise self.error
Response.raise_for_status(self)

Expand Down Expand Up @@ -112,7 +114,7 @@ def __init__(self, base_url, request_event, user, *args, pool_manager: PoolManag
self.mount("https://", LocustHttpAdapter(pool_manager=pool_manager))
self.mount("http://", LocustHttpAdapter(pool_manager=pool_manager))

def _build_url(self, path):
def _build_url(self, path) -> str:
"""prepend url with hostname unless it's already an absolute URL"""
if absolute_http_url_regexp.match(path):
return path
Expand Down Expand Up @@ -191,7 +193,7 @@ def request( # type: ignore[override]
response_time = (time.perf_counter() - start_perf_counter) * 1000

request_before_redirect = (response.history and response.history[0] or response).request
url = request_before_redirect.url
url = request_before_redirect.url # type: ignore

if not name:
name = request_before_redirect.path_url
Expand Down Expand Up @@ -225,7 +227,7 @@ def request( # type: ignore[override]
pass
return response

def _send_request_safe_mode(self, method, url, **kwargs):
def _send_request_safe_mode(self, method, url, **kwargs) -> Response | LocustResponse:
"""
Send an HTTP request, and catch any exception that might occur due to connection problems.
Expand All @@ -238,8 +240,8 @@ def _send_request_safe_mode(self, method, url, **kwargs):
except RequestException as e:
r = LocustResponse()
r.error = e
r.status_code = 0 # with this status_code, content returns None
r.request = Request(method, url).prepare()
r.status_code = 0
r.request = e.request # type: ignore
return r

def get(
Expand Down Expand Up @@ -440,17 +442,11 @@ def init_poolmanager(self, *args, **kwargs):


# Monkey patch Response class to give some guidance
def _success(self):
raise LocustError(
"If you want to change the state of the request, you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
)


def _failure(self):
def _missing_catch_response_True(self, *_args, **_kwargs):
raise LocustError(
"If you want to change the state of the request, you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
"If you want to change the state of the request using .success() or .failure(), you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
)


Response.success = _success # type: ignore[attr-defined]
Response.failure = _failure # type: ignore[attr-defined]
Response.success = _missing_catch_response_True # type: ignore[attr-defined]
Response.failure = _missing_catch_response_True # type: ignore[attr-defined]

0 comments on commit 1a22015

Please sign in to comment.