Skip to content

Commit c5502e7

Browse files
committed
fix(telegram): guard unsupported attachment type with ValidationError (coderabbit)
Addresses CodeRabbit's CHANGES_REQUESTED on #119. `ATTACHMENT_UPLOADS[attachment.type]` raised a bare `KeyError` for any `attachment.type` outside the supported set. `Attachment.type` is a `Literal`, but Python does not enforce Literals at runtime, so an untyped/dynamic caller can supply an out-of-set value. Guard the lookup and raise a `ValidationError` naming the bad type and the supported set, consistent with the other validation paths in `send_attachment`. New `test_rejects_unsupported_attachment_type` is load-bearing — reverting the guard makes the call raise `KeyError` (not `ValidationError`) and the test fails. https://claude.ai/code/session_01FyMxQn2BEAzmwKS1GZczKj
1 parent 262667c commit c5502e7

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

src/chat_sdk/adapters/telegram/adapter.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,11 @@ async def send_attachment(
19021902
"""
19031903
import aiohttp
19041904

1905+
if attachment.type not in ATTACHMENT_UPLOADS:
1906+
raise ValidationError(
1907+
"telegram",
1908+
f"Unsupported attachment type: {attachment.type}. Supported types: {', '.join(ATTACHMENT_UPLOADS)}",
1909+
)
19051910
upload = ATTACHMENT_UPLOADS[attachment.type]
19061911

19071912
data = attachment.data

tests/test_telegram_api.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,32 @@ async def test_rejects_attachment_without_data_or_url(self):
397397

398398
adapter.telegram_fetch.assert_not_called()
399399

400+
@pytest.mark.asyncio
401+
async def test_rejects_unsupported_attachment_type(self):
402+
"""An attachment.type not in ATTACHMENT_UPLOADS raises a clear ValidationError.
403+
404+
``Attachment.type`` is a ``Literal``, but Python does not enforce it at
405+
runtime, so an untyped/dynamic caller can supply an out-of-set value.
406+
Without the guard the per-type dict lookup raises a bare ``KeyError``;
407+
we surface a ``ValidationError`` naming the bad type and the supported
408+
set instead. Load-bearing: reverting the guard makes this raise
409+
``KeyError`` (not ``ValidationError``) and the test fails.
410+
"""
411+
adapter = _make_adapter()
412+
_init_adapter(adapter)
413+
adapter.telegram_fetch = AsyncMock(return_value=_make_telegram_message())
414+
415+
with pytest.raises(ValidationError, match="Unsupported attachment type: sticker"):
416+
await adapter.post_message(
417+
THREAD_ID,
418+
PostableRaw(
419+
raw="",
420+
attachments=[Attachment(type="sticker", data=b"x")], # type: ignore[arg-type]
421+
),
422+
)
423+
424+
adapter.telegram_fetch.assert_not_called()
425+
400426

401427
# =============================================================================
402428
# Tests -- edit_message

0 commit comments

Comments
 (0)