|
1 | 1 | import pytest |
| 2 | +import queue |
| 3 | +import time |
2 | 4 |
|
3 | 5 | from unittest.mock import patch |
4 | 6 |
|
5 | 7 | from telegram import VERSION |
6 | 8 | from telegram.utils import AsyncResult |
7 | 9 | from telegram.client import Telegram, MESSAGE_HANDLER_TYPE, AuthorizationState |
8 | 10 | from telegram.text import Spoiler |
| 11 | +from telegram.worker import SimpleWorker |
9 | 12 |
|
10 | 13 | API_ID = 1 |
11 | 14 | API_HASH = "hash" |
@@ -90,7 +93,10 @@ def test_parse_text_entities(self, telegram): |
90 | 93 |
|
91 | 94 | def test_send_phone_number_or_bot_token(self, telegram): |
92 | 95 | # check that the dunction calls _send_phone_number or _send_bot_token |
93 | | - with patch.object(telegram, "_send_phone_number"), patch.object(telegram, "_send_bot_token"): |
| 96 | + with ( |
| 97 | + patch.object(telegram, "_send_phone_number"), |
| 98 | + patch.object(telegram, "_send_bot_token"), |
| 99 | + ): |
94 | 100 | telegram.phone = "123" |
95 | 101 | telegram.bot_token = None |
96 | 102 |
|
@@ -478,3 +484,43 @@ def _get_async_result(data, request_id=None): |
478 | 484 | assert state == telegram.authorization_state == AuthorizationState.READY |
479 | 485 |
|
480 | 486 | assert telegram._tdjson.send.call_count == 0 |
| 487 | + |
| 488 | + |
| 489 | +class TestWorker: |
| 490 | + def test_worker_continues_after_handler_exception(self): |
| 491 | + """Handler exceptions should not kill the worker thread and task_done must be called""" |
| 492 | + q = queue.Queue() |
| 493 | + worker = SimpleWorker(q) |
| 494 | + worker.run() |
| 495 | + |
| 496 | + results = [] |
| 497 | + |
| 498 | + def failing_handler(update): |
| 499 | + raise ValueError("Handler failed") |
| 500 | + |
| 501 | + def working_handler(update): |
| 502 | + results.append(update) |
| 503 | + |
| 504 | + # Put two items: one with a failing handler, one with a working handler |
| 505 | + q.put((failing_handler, {"id": 1})) |
| 506 | + q.put((working_handler, {"id": 2})) |
| 507 | + |
| 508 | + # Give the worker time to process both items |
| 509 | + time.sleep(1) |
| 510 | + |
| 511 | + worker.stop() |
| 512 | + |
| 513 | + assert results == [{"id": 2}] |
| 514 | + |
| 515 | + def test_run_handlers_continues_on_queue_full(self, telegram): |
| 516 | + """queue.Full should not crash the listener""" |
| 517 | + |
| 518 | + def my_handler(): |
| 519 | + pass |
| 520 | + |
| 521 | + telegram.add_message_handler(my_handler) |
| 522 | + |
| 523 | + # Mock the queue to always raise queue.Full |
| 524 | + with patch.object(telegram._workers_queue, "put", side_effect=queue.Full): |
| 525 | + # This should not raise an exception |
| 526 | + telegram._run_handlers({"@type": MESSAGE_HANDLER_TYPE}) |
0 commit comments