feat: Raise NotFoundError instead of LookupError in wait_for_row_change (#105)

This commit is contained in:
d3vyce
2026-03-02 14:28:37 +01:00
committed by GitHub
parent 56d365d14b
commit 4a020c56d1
2 changed files with 10 additions and 7 deletions

View File

@@ -10,6 +10,8 @@ from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import DeclarativeBase
from .exceptions import NotFoundError
__all__ = [ __all__ = [
"LockMode", "LockMode",
"create_db_context", "create_db_context",
@@ -216,7 +218,7 @@ async def wait_for_row_change(
The refreshed model instance with updated values The refreshed model instance with updated values
Raises: Raises:
LookupError: If the row does not exist or is deleted during polling NotFoundError: If the row does not exist or is deleted during polling
TimeoutError: If timeout expires before a change is detected TimeoutError: If timeout expires before a change is detected
Example: Example:
@@ -237,7 +239,7 @@ async def wait_for_row_change(
""" """
instance = await session.get(model, pk_value) instance = await session.get(model, pk_value)
if instance is None: if instance is None:
raise LookupError(f"{model.__name__} with pk={pk_value!r} not found") raise NotFoundError(f"{model.__name__} with pk={pk_value!r} not found")
if columns is not None: if columns is not None:
watch_cols = columns watch_cols = columns
@@ -261,7 +263,7 @@ async def wait_for_row_change(
instance = await session.get(model, pk_value) instance = await session.get(model, pk_value)
if instance is None: if instance is None:
raise LookupError(f"{model.__name__} with pk={pk_value!r} was deleted") raise NotFoundError(f"{model.__name__} with pk={pk_value!r} was deleted")
current = {col: getattr(instance, col) for col in watch_cols} current = {col: getattr(instance, col) for col in watch_cols}
if current != initial: if current != initial:

View File

@@ -14,6 +14,7 @@ from fastapi_toolsets.db import (
lock_tables, lock_tables,
wait_for_row_change, wait_for_row_change,
) )
from fastapi_toolsets.exceptions import NotFoundError
from .conftest import DATABASE_URL, Base, Role, RoleCrud, User from .conftest import DATABASE_URL, Base, Role, RoleCrud, User
@@ -307,9 +308,9 @@ class TestWaitForRowChange:
@pytest.mark.anyio @pytest.mark.anyio
async def test_nonexistent_row_raises(self, db_session: AsyncSession): async def test_nonexistent_row_raises(self, db_session: AsyncSession):
"""Raises LookupError when the row does not exist.""" """Raises NotFoundError when the row does not exist."""
fake_id = uuid.uuid4() fake_id = uuid.uuid4()
with pytest.raises(LookupError, match="not found"): with pytest.raises(NotFoundError, match="not found"):
await wait_for_row_change(db_session, Role, fake_id, interval=0.05) await wait_for_row_change(db_session, Role, fake_id, interval=0.05)
@pytest.mark.anyio @pytest.mark.anyio
@@ -326,7 +327,7 @@ class TestWaitForRowChange:
@pytest.mark.anyio @pytest.mark.anyio
async def test_deleted_row_raises(self, db_session: AsyncSession, engine): async def test_deleted_row_raises(self, db_session: AsyncSession, engine):
"""Raises LookupError when the row is deleted during polling.""" """Raises NotFoundError when the row is deleted during polling."""
role = Role(name="delete_role") role = Role(name="delete_role")
db_session.add(role) db_session.add(role)
await db_session.commit() await db_session.commit()
@@ -340,6 +341,6 @@ class TestWaitForRowChange:
await other.commit() await other.commit()
delete_task = asyncio.create_task(delete_later()) delete_task = asyncio.create_task(delete_later())
with pytest.raises(LookupError): with pytest.raises(NotFoundError):
await wait_for_row_change(db_session, Role, role.id, interval=0.05) await wait_for_row_change(db_session, Role, role.id, interval=0.05)
await delete_task await delete_task