diff --git a/app/repositories/messages_repository.py b/app/repositories/messages_repository.py index 1ff8caf..36bd7dd 100644 --- a/app/repositories/messages_repository.py +++ b/app/repositories/messages_repository.py @@ -3,8 +3,9 @@ from collections.abc import Sequence import sqlalchemy as sa +from advanced_alchemy.exceptions import wrap_sqlalchemy_exception from advanced_alchemy.filters import LimitOffset -from advanced_alchemy.repository import SQLAlchemyAsyncRepository +from advanced_alchemy.repository import DEFAULT_ERROR_MESSAGE_TEMPLATES, SQLAlchemyAsyncRepository from advanced_alchemy.service import SQLAlchemyAsyncRepositoryService from sqlalchemy.dialects import postgresql @@ -29,9 +30,11 @@ async def get_or_create( ) # xmax is 0 only on a row version this statement inserted. created: typing.Final = sa.literal_column("xmax = 0", sa.Boolean) - message, was_created = ( - await self.repository.session.execute(statement.returning(tables.MessagesTable, created)) - ).one() + with wrap_sqlalchemy_exception(error_messages=DEFAULT_ERROR_MESSAGE_TEMPLATES, dialect_name="postgresql"): + result: typing.Final = await self.repository.session.execute( + statement.returning(tables.MessagesTable, created) + ) + message, was_created = result.one() return message, was_created async def fetch_latest_active(self, chat_id: int) -> tables.MessagesTable | None: diff --git a/tests/use_cases/test_create_message.py b/tests/use_cases/test_create_message.py index 822040c..1ab0be4 100644 --- a/tests/use_cases/test_create_message.py +++ b/tests/use_cases/test_create_message.py @@ -5,6 +5,7 @@ import pytest import sqlalchemy as sa +from advanced_alchemy.exceptions import ForeignKeyError from db_retry import Transaction from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession @@ -99,6 +100,13 @@ async def test_same_idempotency_key_in_two_different_chats_creates_two_messages( assert second.chat_id == other_chat.id +async def test_get_or_create_raises_foreign_key_error_for_an_unknown_chat( + messages_repository: MessagesRepository, alice: Actor +) -> None: + with pytest.raises(ForeignKeyError): + await messages_repository.get_or_create(chat_id=-1, user_id=alice.id, idempotency_key=uuid.uuid4(), text="hi") + + async def test_send_writes_the_message_with_a_single_statement( create_message_use_case: CreateMessageUseCase, direct_chat: tables.ChatsTable,