Skip to content

Commit ab35b3b

Browse files
Harden paginated page param helper validation
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent edb47b8 commit ab35b3b

2 files changed

Lines changed: 75 additions & 3 deletions

File tree

hyperbrowser/client/managers/page_params_utils.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
from typing import Type, TypeVar
1+
from typing import Type, TypeVar, cast
2+
3+
from hyperbrowser.exceptions import HyperbrowserError
4+
from hyperbrowser.type_utils import is_plain_int
25

36
DEFAULT_PAGE_BATCH_SIZE = 100
47

@@ -11,5 +14,20 @@ def build_page_batch_params(
1114
page: int,
1215
batch_size: int = DEFAULT_PAGE_BATCH_SIZE,
1316
) -> T:
14-
params_model_obj = params_model
15-
return params_model_obj(page=page, batch_size=batch_size) # type: ignore[call-arg]
17+
if not is_plain_int(page):
18+
raise HyperbrowserError("page must be a plain integer")
19+
if page <= 0:
20+
raise HyperbrowserError("page must be a positive integer")
21+
if not is_plain_int(batch_size):
22+
raise HyperbrowserError("batch_size must be a plain integer")
23+
if batch_size <= 0:
24+
raise HyperbrowserError("batch_size must be a positive integer")
25+
try:
26+
return cast(T, params_model(page=page, batch_size=batch_size))
27+
except HyperbrowserError:
28+
raise
29+
except Exception as exc:
30+
raise HyperbrowserError(
31+
"Failed to build paginated page params",
32+
original_error=exc,
33+
) from exc

tests/test_page_params_utils.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import pytest
2+
13
from hyperbrowser.client.managers.page_params_utils import (
24
DEFAULT_PAGE_BATCH_SIZE,
35
build_page_batch_params,
46
)
7+
from hyperbrowser.exceptions import HyperbrowserError
58
from hyperbrowser.models.crawl import GetCrawlJobParams
69
from hyperbrowser.models.scrape import GetBatchScrapeJobParams
710

@@ -20,3 +23,54 @@ def test_build_page_batch_params_accepts_custom_batch_size():
2023
assert isinstance(params, GetCrawlJobParams)
2124
assert params.page == 2
2225
assert params.batch_size == 25
26+
27+
28+
def test_build_page_batch_params_rejects_non_plain_int_page():
29+
with pytest.raises(HyperbrowserError, match="page must be a plain integer"):
30+
build_page_batch_params(GetBatchScrapeJobParams, page=True) # type: ignore[arg-type]
31+
32+
33+
def test_build_page_batch_params_rejects_non_positive_page():
34+
with pytest.raises(HyperbrowserError, match="page must be a positive integer"):
35+
build_page_batch_params(GetBatchScrapeJobParams, page=0)
36+
37+
38+
def test_build_page_batch_params_rejects_non_plain_int_batch_size():
39+
class _IntSubclass(int):
40+
pass
41+
42+
with pytest.raises(HyperbrowserError, match="batch_size must be a plain integer"):
43+
build_page_batch_params(
44+
GetBatchScrapeJobParams,
45+
page=1,
46+
batch_size=_IntSubclass(10), # type: ignore[arg-type]
47+
)
48+
49+
50+
def test_build_page_batch_params_rejects_non_positive_batch_size():
51+
with pytest.raises(HyperbrowserError, match="batch_size must be a positive integer"):
52+
build_page_batch_params(GetBatchScrapeJobParams, page=1, batch_size=0)
53+
54+
55+
def test_build_page_batch_params_wraps_runtime_constructor_errors():
56+
class _BrokenParams:
57+
def __init__(self, *, page, batch_size): # noqa: ARG002
58+
raise RuntimeError("boom")
59+
60+
with pytest.raises(
61+
HyperbrowserError, match="Failed to build paginated page params"
62+
) as exc_info:
63+
build_page_batch_params(_BrokenParams, page=1)
64+
65+
assert isinstance(exc_info.value.original_error, RuntimeError)
66+
67+
68+
def test_build_page_batch_params_preserves_hyperbrowser_errors():
69+
class _BrokenParams:
70+
def __init__(self, *, page, batch_size): # noqa: ARG002
71+
raise HyperbrowserError("custom failure")
72+
73+
with pytest.raises(HyperbrowserError, match="custom failure") as exc_info:
74+
build_page_batch_params(_BrokenParams, page=1)
75+
76+
assert exc_info.value.original_error is None

0 commit comments

Comments
 (0)