diff --git a/routstr/core/db.py b/routstr/core/db.py index 9ebb87e9..6e629da1 100644 --- a/routstr/core/db.py +++ b/routstr/core/db.py @@ -288,29 +288,22 @@ async def store_cashu_transaction( source: str = "x-cashu", api_key_hashed_key: str | None = None, ) -> bool: - try: - async with create_session() as session: - tx = CashuTransaction( - token=token, - amount=amount, - unit=unit, - mint_url=mint_url, - type=typ, - request_id=request_id, - collected=collected, - created_at=created_at or int(time.time()), - source=source, - api_key_hashed_key=api_key_hashed_key, - ) - session.add(tx) - await session.commit() - return True - except Exception as e: - logger.warning( - f"Failed to store cashu transaction: {e} (type={typ})", - extra={"error": str(e), "type": typ}, + async with create_session() as session: + tx = CashuTransaction( + token=token, + amount=amount, + unit=unit, + mint_url=mint_url, + type=typ, + request_id=request_id, + collected=collected, + created_at=created_at or int(time.time()), + source=source, + api_key_hashed_key=api_key_hashed_key, ) - return False + session.add(tx) + await session.commit() + return True class UpstreamProviderRow(SQLModel, table=True): # type: ignore diff --git a/tests/unit/test_cashu_transaction_storage_errors.py b/tests/unit/test_cashu_transaction_storage_errors.py new file mode 100644 index 00000000..cc6d5221 --- /dev/null +++ b/tests/unit/test_cashu_transaction_storage_errors.py @@ -0,0 +1,51 @@ +from unittest.mock import AsyncMock, patch + +import pytest + +from routstr.core.db import store_cashu_transaction + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "error", + [ + OSError("disk full"), + RuntimeError("connection lost"), + ConnectionRefusedError("database unavailable"), + ], +) +async def test_store_cashu_transaction_propagates_commit_errors( + error: Exception, +) -> None: + session = AsyncMock() + session.commit.side_effect = error + session.__aenter__.return_value = session + session.__aexit__.return_value = None + + with patch("routstr.core.db.create_session", return_value=session): + with pytest.raises(type(error), match=str(error)): + await store_cashu_transaction( + token="cashuAtest", + amount=1_000, + unit="sat", + mint_url="https://mint.example", + typ="out", + request_id="request-1", + ) + + +@pytest.mark.asyncio +async def test_store_cashu_transaction_returns_true_after_commit() -> None: + session = AsyncMock() + session.__aenter__.return_value = session + session.__aexit__.return_value = None + + with patch("routstr.core.db.create_session", return_value=session): + stored = await store_cashu_transaction( + token="cashuAtest", + amount=1_000, + unit="sat", + ) + + assert stored is True + session.commit.assert_awaited_once()