0
# Error Handling
1
2
Comprehensive error handling system with specific exception types for different error conditions and RPC errors from Telegram in Telethon.
3
4
## Capabilities
5
6
### Base Error Classes
7
8
Foundation error classes for different categories of errors.
9
10
```python { .api }
11
class TelethonException(Exception):
12
"""Base exception for all Telethon-specific errors."""
13
14
class RPCError(TelethonException):
15
"""
16
Base class for all RPC (Remote Procedure Call) errors from Telegram.
17
18
Attributes:
19
- code: Numeric error code from Telegram
20
- message: Error message from Telegram
21
- request: The request that caused this error
22
"""
23
def __init__(self, message: str, request=None, code: int = None):
24
"""
25
Initialize RPC error.
26
27
Parameters:
28
- message: Error message from Telegram
29
- request: The request that triggered the error
30
- code: Telegram error code
31
"""
32
33
code: int
34
message: str
35
request: Any
36
37
class ReadCancelledError(TelethonException):
38
"""Raised when a read operation is cancelled."""
39
40
class TypeNotFoundError(TelethonException):
41
"""Raised when a TL type cannot be found."""
42
43
class InvalidChecksumError(TelethonException):
44
"""Raised when data integrity check fails."""
45
46
class InvalidBufferError(TelethonException):
47
"""Raised when buffer data is invalid or corrupted."""
48
49
class SecurityError(TelethonException):
50
"""Raised when a security check fails."""
51
52
class CdnFileTamperedError(SecurityError):
53
"""Raised when a CDN file appears to be tampered with."""
54
55
class AlreadyInConversationError(TelethonException):
56
"""Raised when trying to start a conversation that's already active."""
57
58
class BadMessageError(TelethonException):
59
"""Raised when message format is invalid."""
60
61
class MultiError(TelethonException):
62
"""Container for multiple errors that occurred together."""
63
64
def __init__(self, exceptions: List[Exception]):
65
"""
66
Initialize with list of exceptions.
67
68
Parameters:
69
- exceptions: List of exceptions that occurred
70
"""
71
72
exceptions: List[Exception]
73
```
74
75
### Authentication Errors
76
77
Errors related to user authentication and session management.
78
79
```python { .api }
80
class AuthKeyNotFound(TelethonException):
81
"""Raised when authorization key is missing or invalid."""
82
83
class SessionPasswordNeededError(RPCError):
84
"""
85
Raised when two-factor authentication password is required.
86
87
Handle this by prompting user for 2FA password and calling
88
client.sign_in(password=password).
89
"""
90
91
class PhoneCodeInvalidError(RPCError):
92
"""
93
Raised when verification code is incorrect.
94
95
User should be prompted to enter the code again.
96
"""
97
98
class PhoneCodeExpiredError(RPCError):
99
"""
100
Raised when verification code has expired.
101
102
Request a new code with client.send_code_request().
103
"""
104
105
class PhoneNumberInvalidError(RPCError):
106
"""
107
Raised when phone number format is invalid.
108
109
Ensure phone number is in international format (+1234567890).
110
"""
111
112
class PhonePasswordFloodError(RPCError):
113
"""
114
Raised when too many 2FA password attempts made.
115
116
Wait before attempting again.
117
"""
118
119
class PasswordHashInvalidError(RPCError):
120
"""
121
Raised when 2FA password is incorrect.
122
123
User should be prompted to enter password again.
124
"""
125
```
126
127
### Request Errors
128
129
HTTP-style error codes for different request problems.
130
131
```python { .api }
132
class BadRequestError(RPCError):
133
"""
134
Base class for 400-style errors (client errors).
135
136
Indicates the request was malformed or invalid.
137
"""
138
139
class UnauthorizedError(RPCError):
140
"""
141
Base class for 401-style errors (authorization errors).
142
143
User needs to authenticate or re-authenticate.
144
"""
145
146
class ForbiddenError(RPCError):
147
"""
148
Base class for 403-style errors (permission errors).
149
150
User lacks required permissions for the operation.
151
"""
152
153
class NotFoundError(RPCError):
154
"""
155
Base class for 404-style errors (not found errors).
156
157
Requested resource (user, chat, message) doesn't exist.
158
"""
159
160
class FloodWaitError(RPCError):
161
"""
162
Base class for 420-style errors (rate limiting).
163
164
Too many requests made, must wait before retrying.
165
166
Attributes:
167
- seconds: Number of seconds to wait before retrying
168
"""
169
170
def __init__(self, message: str, request=None, seconds: int = None):
171
"""
172
Initialize flood wait error.
173
174
Parameters:
175
- message: Error message
176
- request: Request that was rate limited
177
- seconds: Wait time in seconds
178
"""
179
180
seconds: int
181
182
class InternalServerError(RPCError):
183
"""
184
Base class for 500-style errors (server errors).
185
186
Telegram server encountered an error processing the request.
187
"""
188
```
189
190
### Chat and User Errors
191
192
Errors specific to chat operations and user management.
193
194
```python { .api }
195
class ChatAdminRequiredError(ForbiddenError):
196
"""
197
Raised when admin privileges are required for an operation.
198
199
User must be promoted to admin with appropriate permissions.
200
"""
201
202
class ChatWriteForbiddenError(ForbiddenError):
203
"""
204
Raised when user cannot write messages to a chat.
205
206
User may be banned, restricted, or chat may be read-only.
207
"""
208
209
class UserNotParticipantError(BadRequestError):
210
"""
211
Raised when user is not a member of the chat.
212
213
User must join the chat before performing operations.
214
"""
215
216
class UserBannedInChannelError(ForbiddenError):
217
"""
218
Raised when user is banned from a channel/supergroup.
219
220
User must be unbanned by an admin.
221
"""
222
223
class UserRestrictedError(ForbiddenError):
224
"""
225
Raised when user is restricted in a chat.
226
227
Admin can remove restrictions or wait for timeout.
228
"""
229
230
class UsernameNotOccupiedError(NotFoundError):
231
"""
232
Raised when username doesn't exist.
233
234
Check username spelling or try alternative methods.
235
"""
236
237
class UserIdInvalidError(BadRequestError):
238
"""
239
Raised when user ID is invalid or malformed.
240
241
Verify the user ID is correct.
242
"""
243
```
244
245
### Message Errors
246
247
Errors related to message operations.
248
249
```python { .api }
250
class MessageNotModifiedError(BadRequestError):
251
"""
252
Raised when trying to edit message without changes.
253
254
Ensure new content differs from current content.
255
"""
256
257
class MessageEditTimeExpiredError(ForbiddenError):
258
"""
259
Raised when message edit time window has expired.
260
261
Messages can only be edited for 48 hours after sending.
262
"""
263
264
class MessageIdInvalidError(BadRequestError):
265
"""
266
Raised when message ID doesn't exist or is invalid.
267
268
Verify the message ID is correct and message exists.
269
"""
270
271
class MessageTooLongError(BadRequestError):
272
"""
273
Raised when message exceeds length limits.
274
275
Text messages are limited to 4096 characters.
276
"""
277
278
class MessageDeleteForbiddenError(ForbiddenError):
279
"""
280
Raised when user cannot delete the message.
281
282
User must be message author or have admin delete permissions.
283
"""
284
285
class MessageAuthorRequiredError(ForbiddenError):
286
"""
287
Raised when operation requires message author.
288
289
Only the message author can perform this operation.
290
"""
291
```
292
293
### File and Media Errors
294
295
Errors related to file uploads and downloads.
296
297
```python { .api }
298
class FilePartMissingError(BadRequestError):
299
"""
300
Raised when file upload is incomplete.
301
302
Some parts of the file were not uploaded successfully.
303
"""
304
305
class FileTooLargeError(BadRequestError):
306
"""
307
Raised when file exceeds size limits.
308
309
Regular files: 2GB, thumbnails: 200KB.
310
"""
311
312
class MediaInvalidError(BadRequestError):
313
"""
314
Raised when media format is invalid or unsupported.
315
316
Check file format and try a different file.
317
"""
318
319
class FileReferenceExpiredError(BadRequestError):
320
"""
321
Raised when file reference has expired.
322
323
Re-fetch the media object to get fresh references.
324
"""
325
326
class MediaEmptyError(BadRequestError):
327
"""
328
Raised when message has no media to download.
329
330
Check if message contains media before downloading.
331
"""
332
```
333
334
### Network and Connection Errors
335
336
Errors related to network connectivity and datacenter issues.
337
338
```python { .api }
339
class InvalidDCError(BadRequestError):
340
"""
341
Raised when datacenter ID is invalid.
342
343
Valid datacenter IDs are 1-5 for production.
344
"""
345
346
class DatacenterMigrateError(RPCError):
347
"""
348
Raised when operation must be performed on different datacenter.
349
350
Client automatically handles this by migrating.
351
352
Attributes:
353
- new_dc: Target datacenter ID
354
"""
355
356
new_dc: int
357
358
class NetworkMigrateError(RPCError):
359
"""
360
Raised when network configuration has changed.
361
362
Client should reconnect to handle this.
363
"""
364
```
365
366
### Error Conversion
367
368
Convert Telegram RPC errors to appropriate Python exceptions.
369
370
```python { .api }
371
def rpc_message_to_error(rpc_error, request) -> RPCError:
372
"""
373
Convert Telegram RPC error to appropriate Python exception.
374
375
Parameters:
376
- rpc_error: RpcError object from Telegram
377
- request: The request that caused the error
378
379
Returns:
380
RPCError: Appropriate exception subclass
381
382
This function maps Telegram error messages to specific
383
Python exception types for better error handling.
384
"""
385
```
386
387
## Usage Examples
388
389
### Basic Error Handling
390
391
```python
392
import asyncio
393
from telethon import TelegramClient
394
from telethon.errors import (
395
SessionPasswordNeededError, PhoneCodeInvalidError,
396
FloodWaitError, ChatWriteForbiddenError
397
)
398
399
async def basic_error_handling():
400
client = TelegramClient('session', api_id, api_hash)
401
await client.connect()
402
403
try:
404
# Attempt to sign in
405
phone = '+1234567890'
406
await client.send_code_request(phone)
407
code = input('Enter code: ')
408
await client.sign_in(phone, code)
409
410
except SessionPasswordNeededError:
411
# 2FA is enabled
412
password = input('Enter 2FA password: ')
413
await client.sign_in(password=password)
414
415
except PhoneCodeInvalidError:
416
print('Invalid verification code. Please try again.')
417
return
418
419
except FloodWaitError as e:
420
print(f'Rate limited. Wait {e.seconds} seconds.')
421
await asyncio.sleep(e.seconds)
422
423
# Try to send a message
424
try:
425
await client.send_message('username', 'Hello!')
426
427
except ChatWriteForbiddenError:
428
print('Cannot write to this chat (banned/restricted)')
429
430
except FloodWaitError as e:
431
print(f'Message rate limited. Wait {e.seconds} seconds.')
432
433
await client.disconnect()
434
435
asyncio.run(basic_error_handling())
436
```
437
438
### Advanced Error Handling with Retry Logic
439
440
```python
441
import asyncio
442
import random
443
from telethon.errors import FloodWaitError, RPCError
444
445
async def send_with_retry(client, entity, message, max_retries=3):
446
"""Send message with automatic retry on certain errors."""
447
448
for attempt in range(max_retries):
449
try:
450
return await client.send_message(entity, message)
451
452
except FloodWaitError as e:
453
if attempt < max_retries - 1:
454
wait_time = min(e.seconds, 300) # Cap at 5 minutes
455
print(f'Rate limited. Waiting {wait_time} seconds...')
456
await asyncio.sleep(wait_time)
457
continue
458
else:
459
print('Max retries reached for flood wait')
460
raise
461
462
except RPCError as e:
463
if e.code == 500: # Internal server error
464
if attempt < max_retries - 1:
465
wait_time = (2 ** attempt) + random.uniform(0, 1)
466
print(f'Server error. Retrying in {wait_time:.1f} seconds...')
467
await asyncio.sleep(wait_time)
468
continue
469
else:
470
print('Max retries reached for server error')
471
raise
472
else:
473
# Don't retry other RPC errors
474
raise
475
476
except Exception as e:
477
# Don't retry non-RPC errors
478
print(f'Unexpected error: {e}')
479
raise
480
481
return None
482
483
async def retry_example():
484
client = TelegramClient('session', api_id, api_hash)
485
await client.start()
486
487
try:
488
message = await send_with_retry(
489
client,
490
'username',
491
'This message will retry on errors'
492
)
493
if message:
494
print('Message sent successfully!')
495
else:
496
print('Failed to send message after retries')
497
498
except Exception as e:
499
print(f'Final error: {e}')
500
501
await client.disconnect()
502
```
503
504
### Specific Error Handling Patterns
505
506
```python
507
from telethon.errors import (
508
MessageNotModifiedError, MessageEditTimeExpiredError,
509
FilePartMissingError, FileTooLargeError,
510
UserNotParticipantError, ChatAdminRequiredError
511
)
512
513
async def specific_error_patterns():
514
client = TelegramClient('session', api_id, api_hash)
515
await client.start()
516
517
# Message editing errors
518
try:
519
await client.edit_message('username', message_id, 'New text')
520
521
except MessageNotModifiedError:
522
print('Message content is the same, no changes made')
523
524
except MessageEditTimeExpiredError:
525
print('Cannot edit message - too much time has passed')
526
527
except MessageIdInvalidError:
528
print('Message not found or invalid ID')
529
530
# File upload errors
531
try:
532
await client.send_file('username', 'large_file.zip')
533
534
except FileTooLargeError:
535
print('File is too large (2GB limit)')
536
537
except FilePartMissingError:
538
print('File upload incomplete, retrying...')
539
# Could implement retry logic here
540
541
except MediaInvalidError:
542
print('File format not supported')
543
544
# Chat management errors
545
try:
546
await client.kick_participant('group_chat', 'user_to_kick')
547
548
except ChatAdminRequiredError:
549
print('Need admin privileges to kick users')
550
551
except UserNotParticipantError:
552
print('User is not in the chat')
553
554
except UserBannedInChannelError:
555
print('User is already banned')
556
557
await client.disconnect()
558
```
559
560
### Error Logging and Monitoring
561
562
```python
563
import logging
564
from telethon.errors import RPCError
565
566
# Set up logging
567
logging.basicConfig(
568
level=logging.INFO,
569
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
570
)
571
logger = logging.getLogger(__name__)
572
573
async def monitored_operation(client, operation_name, operation_func, *args, **kwargs):
574
"""Execute operation with comprehensive error logging."""
575
576
try:
577
logger.info(f'Starting {operation_name}')
578
result = await operation_func(*args, **kwargs)
579
logger.info(f'Completed {operation_name} successfully')
580
return result
581
582
except FloodWaitError as e:
583
logger.warning(f'{operation_name} rate limited: wait {e.seconds}s')
584
raise
585
586
except RPCError as e:
587
logger.error(f'{operation_name} RPC error: {e.message} (code: {e.code})')
588
logger.debug(f'Request that caused error: {e.request}')
589
raise
590
591
except Exception as e:
592
logger.error(f'{operation_name} unexpected error: {e}')
593
logger.exception('Full traceback:')
594
raise
595
596
async def monitored_example():
597
client = TelegramClient('session', api_id, api_hash)
598
await client.start()
599
600
# Monitor different operations
601
await monitored_operation(
602
client, 'send_message',
603
client.send_message, 'username', 'Hello!'
604
)
605
606
await monitored_operation(
607
client, 'get_participants',
608
client.get_participants, 'group_chat'
609
)
610
611
await client.disconnect()
612
```
613
614
### Custom Error Handler Context Manager
615
616
```python
617
from contextlib import asynccontextmanager
618
from telethon.errors import FloodWaitError, RPCError
619
620
@asynccontextmanager
621
async def handle_telegram_errors(
622
ignore_flood: bool = False,
623
max_flood_wait: int = 300,
624
retry_server_errors: bool = True
625
):
626
"""
627
Context manager for common Telegram error handling patterns.
628
629
Parameters:
630
- ignore_flood: Whether to silently handle flood waits
631
- max_flood_wait: Maximum seconds to wait for flood errors
632
- retry_server_errors: Whether to retry on server errors
633
"""
634
635
try:
636
yield
637
638
except FloodWaitError as e:
639
if ignore_flood and e.seconds <= max_flood_wait:
640
print(f'Waiting {e.seconds} seconds for rate limit...')
641
await asyncio.sleep(e.seconds)
642
else:
643
print(f'Rate limited for {e.seconds} seconds')
644
raise
645
646
except RPCError as e:
647
if e.code == 500 and retry_server_errors:
648
print('Server error occurred, operation may need retry')
649
650
# Log the error details
651
print(f'Telegram error: {e.message} (code: {e.code})')
652
raise
653
654
except Exception as e:
655
print(f'Unexpected error: {e}')
656
raise
657
658
async def context_manager_example():
659
client = TelegramClient('session', api_id, api_hash)
660
await client.start()
661
662
# Use context manager for error handling
663
async with handle_telegram_errors(ignore_flood=True, max_flood_wait=60):
664
await client.send_message('username', 'Protected message')
665
666
async with handle_telegram_errors(retry_server_errors=False):
667
participants = await client.get_participants('large_group')
668
print(f'Got {len(participants)} participants')
669
670
await client.disconnect()
671
```
672
673
## Types
674
675
```python { .api }
676
from typing import Optional, List, Any, Union
677
import asyncio
678
679
ErrorCode = int
680
ErrorMessage = str
681
WaitSeconds = int
682
683
class ErrorInfo:
684
"""Information about a Telegram error"""
685
code: ErrorCode
686
message: ErrorMessage
687
request: Optional[Any]
688
wait_time: Optional[WaitSeconds]
689
690
ErrorHandler = Union[
691
Callable[[Exception], None],
692
Callable[[Exception], Awaitable[None]]
693
]
694
695
RetryStrategy = Callable[[int, Exception], Union[bool, Awaitable[bool]]]
696
```