From baa9711665818f2fa14ca76e95e737fb12670960 Mon Sep 17 00:00:00 2001 From: d3vyce <44915747+d3vyce@users.noreply.github.com> Date: Sat, 7 Feb 2026 17:39:07 +0100 Subject: [PATCH] feat: add detail if get_obj_by_attr raise StopIteration (#40) --- src/fastapi_toolsets/fixtures/utils.py | 9 +++++++-- tests/test_fixtures.py | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/fastapi_toolsets/fixtures/utils.py b/src/fastapi_toolsets/fixtures/utils.py index a9a4154..7c2acfb 100644 --- a/src/fastapi_toolsets/fixtures/utils.py +++ b/src/fastapi_toolsets/fixtures/utils.py @@ -29,9 +29,14 @@ def get_obj_by_attr( The first model instance where the attribute matches the given value. Raises: - StopIteration: If no matching object is found. + StopIteration: If no matching object is found in the fixture group. """ - return next(obj for obj in fixtures() if getattr(obj, attr_name) == value) + try: + return next(obj for obj in fixtures() if getattr(obj, attr_name) == value) + except StopIteration: + raise StopIteration( + f"No object with {attr_name}={value} found in fixture '{getattr(fixtures, '__name__', repr(fixtures))}'" + ) from None async def load_fixtures( diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 6e0dcea..8e465b1 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -744,8 +744,11 @@ class TestGetObjByAttr: assert user.username == "alice" def test_no_match_raises_stop_iteration(self): - """Raises StopIteration when no object matches.""" - with pytest.raises(StopIteration): + """Raises StopIteration with contextual message when no object matches.""" + with pytest.raises( + StopIteration, + match="No object with name=nonexistent found in fixture 'roles'", + ): get_obj_by_attr(self.roles, "name", "nonexistent") def test_no_match_on_wrong_value_type(self):