CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-telethon

Full-featured Telegram client library for Python 3

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error handling system with specific exception types for different error conditions and RPC errors from Telegram in Telethon.

Capabilities

Base Error Classes

Foundation error classes for different categories of errors.

class TelethonException(Exception):
    """Base exception for all Telethon-specific errors."""

class RPCError(TelethonException):
    """
    Base class for all RPC (Remote Procedure Call) errors from Telegram.
    
    Attributes:
    - code: Numeric error code from Telegram
    - message: Error message from Telegram
    - request: The request that caused this error
    """
    def __init__(self, message: str, request=None, code: int = None):
        """
        Initialize RPC error.
        
        Parameters:
        - message: Error message from Telegram
        - request: The request that triggered the error
        - code: Telegram error code
        """
    
    code: int
    message: str
    request: Any

class ReadCancelledError(TelethonException):
    """Raised when a read operation is cancelled."""

class TypeNotFoundError(TelethonException):
    """Raised when a TL type cannot be found."""

class InvalidChecksumError(TelethonException):
    """Raised when data integrity check fails."""

class InvalidBufferError(TelethonException):
    """Raised when buffer data is invalid or corrupted."""

class SecurityError(TelethonException):
    """Raised when a security check fails."""

class CdnFileTamperedError(SecurityError):
    """Raised when a CDN file appears to be tampered with."""

class AlreadyInConversationError(TelethonException):
    """Raised when trying to start a conversation that's already active."""

class BadMessageError(TelethonException):
    """Raised when message format is invalid."""

class MultiError(TelethonException):
    """Container for multiple errors that occurred together."""
    
    def __init__(self, exceptions: List[Exception]):
        """
        Initialize with list of exceptions.
        
        Parameters:
        - exceptions: List of exceptions that occurred
        """
    
    exceptions: List[Exception]

Authentication Errors

Errors related to user authentication and session management.

class AuthKeyNotFound(TelethonException):
    """Raised when authorization key is missing or invalid."""

class SessionPasswordNeededError(RPCError):
    """
    Raised when two-factor authentication password is required.
    
    Handle this by prompting user for 2FA password and calling
    client.sign_in(password=password).
    """

class PhoneCodeInvalidError(RPCError):
    """
    Raised when verification code is incorrect.
    
    User should be prompted to enter the code again.
    """

class PhoneCodeExpiredError(RPCError):
    """
    Raised when verification code has expired.
    
    Request a new code with client.send_code_request().
    """

class PhoneNumberInvalidError(RPCError):
    """
    Raised when phone number format is invalid.
    
    Ensure phone number is in international format (+1234567890).
    """

class PhonePasswordFloodError(RPCError):
    """
    Raised when too many 2FA password attempts made.
    
    Wait before attempting again.
    """

class PasswordHashInvalidError(RPCError):
    """
    Raised when 2FA password is incorrect.
    
    User should be prompted to enter password again.
    """

Request Errors

HTTP-style error codes for different request problems.

class BadRequestError(RPCError):
    """
    Base class for 400-style errors (client errors).
    
    Indicates the request was malformed or invalid.
    """

class UnauthorizedError(RPCError):
    """
    Base class for 401-style errors (authorization errors).
    
    User needs to authenticate or re-authenticate.
    """

class ForbiddenError(RPCError):
    """
    Base class for 403-style errors (permission errors).
    
    User lacks required permissions for the operation.
    """

class NotFoundError(RPCError):
    """
    Base class for 404-style errors (not found errors).
    
    Requested resource (user, chat, message) doesn't exist.
    """

class FloodWaitError(RPCError):
    """
    Base class for 420-style errors (rate limiting).
    
    Too many requests made, must wait before retrying.
    
    Attributes:
    - seconds: Number of seconds to wait before retrying
    """
    
    def __init__(self, message: str, request=None, seconds: int = None):
        """
        Initialize flood wait error.
        
        Parameters:
        - message: Error message
        - request: Request that was rate limited
        - seconds: Wait time in seconds
        """
    
    seconds: int

class InternalServerError(RPCError):
    """
    Base class for 500-style errors (server errors).
    
    Telegram server encountered an error processing the request.
    """

Chat and User Errors

Errors specific to chat operations and user management.

class ChatAdminRequiredError(ForbiddenError):
    """
    Raised when admin privileges are required for an operation.
    
    User must be promoted to admin with appropriate permissions.
    """

class ChatWriteForbiddenError(ForbiddenError):
    """
    Raised when user cannot write messages to a chat.
    
    User may be banned, restricted, or chat may be read-only.
    """

class UserNotParticipantError(BadRequestError):
    """
    Raised when user is not a member of the chat.
    
    User must join the chat before performing operations.
    """

class UserBannedInChannelError(ForbiddenError):
    """
    Raised when user is banned from a channel/supergroup.
    
    User must be unbanned by an admin.
    """

class UserRestrictedError(ForbiddenError):
    """
    Raised when user is restricted in a chat.
    
    Admin can remove restrictions or wait for timeout.
    """

class UsernameNotOccupiedError(NotFoundError):
    """
    Raised when username doesn't exist.
    
    Check username spelling or try alternative methods.
    """

class UserIdInvalidError(BadRequestError):
    """
    Raised when user ID is invalid or malformed.
    
    Verify the user ID is correct.
    """

Message Errors

Errors related to message operations.

class MessageNotModifiedError(BadRequestError):
    """
    Raised when trying to edit message without changes.
    
    Ensure new content differs from current content.
    """

class MessageEditTimeExpiredError(ForbiddenError):
    """
    Raised when message edit time window has expired.
    
    Messages can only be edited for 48 hours after sending.
    """

class MessageIdInvalidError(BadRequestError):
    """
    Raised when message ID doesn't exist or is invalid.
    
    Verify the message ID is correct and message exists.
    """

class MessageTooLongError(BadRequestError):
    """
    Raised when message exceeds length limits.
    
    Text messages are limited to 4096 characters.
    """

class MessageDeleteForbiddenError(ForbiddenError):
    """
    Raised when user cannot delete the message.
    
    User must be message author or have admin delete permissions.
    """

class MessageAuthorRequiredError(ForbiddenError):
    """
    Raised when operation requires message author.
    
    Only the message author can perform this operation.
    """

File and Media Errors

Errors related to file uploads and downloads.

class FilePartMissingError(BadRequestError):
    """
    Raised when file upload is incomplete.
    
    Some parts of the file were not uploaded successfully.
    """

class FileTooLargeError(BadRequestError):
    """
    Raised when file exceeds size limits.
    
    Regular files: 2GB, thumbnails: 200KB.
    """

class MediaInvalidError(BadRequestError):
    """
    Raised when media format is invalid or unsupported.
    
    Check file format and try a different file.
    """

class FileReferenceExpiredError(BadRequestError):
    """
    Raised when file reference has expired.
    
    Re-fetch the media object to get fresh references.
    """

class MediaEmptyError(BadRequestError):
    """
    Raised when message has no media to download.
    
    Check if message contains media before downloading.
    """

Network and Connection Errors

Errors related to network connectivity and datacenter issues.

class InvalidDCError(BadRequestError):
    """
    Raised when datacenter ID is invalid.
    
    Valid datacenter IDs are 1-5 for production.
    """

class DatacenterMigrateError(RPCError):
    """
    Raised when operation must be performed on different datacenter.
    
    Client automatically handles this by migrating.
    
    Attributes:
    - new_dc: Target datacenter ID
    """
    
    new_dc: int

class NetworkMigrateError(RPCError):
    """
    Raised when network configuration has changed.
    
    Client should reconnect to handle this.
    """

Error Conversion

Convert Telegram RPC errors to appropriate Python exceptions.

def rpc_message_to_error(rpc_error, request) -> RPCError:
    """
    Convert Telegram RPC error to appropriate Python exception.
    
    Parameters:
    - rpc_error: RpcError object from Telegram
    - request: The request that caused the error
    
    Returns:
    RPCError: Appropriate exception subclass
    
    This function maps Telegram error messages to specific
    Python exception types for better error handling.
    """

Usage Examples

Basic Error Handling

import asyncio
from telethon import TelegramClient
from telethon.errors import (
    SessionPasswordNeededError, PhoneCodeInvalidError,
    FloodWaitError, ChatWriteForbiddenError
)

async def basic_error_handling():
    client = TelegramClient('session', api_id, api_hash)
    await client.connect()
    
    try:
        # Attempt to sign in
        phone = '+1234567890'
        await client.send_code_request(phone)
        code = input('Enter code: ')
        await client.sign_in(phone, code)
        
    except SessionPasswordNeededError:
        # 2FA is enabled
        password = input('Enter 2FA password: ')
        await client.sign_in(password=password)
        
    except PhoneCodeInvalidError:
        print('Invalid verification code. Please try again.')
        return
        
    except FloodWaitError as e:
        print(f'Rate limited. Wait {e.seconds} seconds.')
        await asyncio.sleep(e.seconds)
        
    # Try to send a message
    try:
        await client.send_message('username', 'Hello!')
        
    except ChatWriteForbiddenError:
        print('Cannot write to this chat (banned/restricted)')
        
    except FloodWaitError as e:
        print(f'Message rate limited. Wait {e.seconds} seconds.')
        
    await client.disconnect()

asyncio.run(basic_error_handling())

Advanced Error Handling with Retry Logic

import asyncio
import random
from telethon.errors import FloodWaitError, RPCError

async def send_with_retry(client, entity, message, max_retries=3):
    """Send message with automatic retry on certain errors."""
    
    for attempt in range(max_retries):
        try:
            return await client.send_message(entity, message)
            
        except FloodWaitError as e:
            if attempt < max_retries - 1:
                wait_time = min(e.seconds, 300)  # Cap at 5 minutes
                print(f'Rate limited. Waiting {wait_time} seconds...')
                await asyncio.sleep(wait_time)
                continue
            else:
                print('Max retries reached for flood wait')
                raise
                
        except RPCError as e:
            if e.code == 500:  # Internal server error
                if attempt < max_retries - 1:
                    wait_time = (2 ** attempt) + random.uniform(0, 1)
                    print(f'Server error. Retrying in {wait_time:.1f} seconds...')
                    await asyncio.sleep(wait_time)
                    continue
                else:
                    print('Max retries reached for server error')
                    raise
            else:
                # Don't retry other RPC errors
                raise
                
        except Exception as e:
            # Don't retry non-RPC errors
            print(f'Unexpected error: {e}')
            raise
    
    return None

async def retry_example():
    client = TelegramClient('session', api_id, api_hash)
    await client.start()
    
    try:
        message = await send_with_retry(
            client, 
            'username', 
            'This message will retry on errors'
        )
        if message:
            print('Message sent successfully!')
        else:
            print('Failed to send message after retries')
            
    except Exception as e:
        print(f'Final error: {e}')
    
    await client.disconnect()

Specific Error Handling Patterns

from telethon.errors import (
    MessageNotModifiedError, MessageEditTimeExpiredError,
    FilePartMissingError, FileTooLargeError,
    UserNotParticipantError, ChatAdminRequiredError
)

async def specific_error_patterns():
    client = TelegramClient('session', api_id, api_hash)
    await client.start()
    
    # Message editing errors
    try:
        await client.edit_message('username', message_id, 'New text')
        
    except MessageNotModifiedError:
        print('Message content is the same, no changes made')
        
    except MessageEditTimeExpiredError:
        print('Cannot edit message - too much time has passed')
        
    except MessageIdInvalidError:
        print('Message not found or invalid ID')
    
    # File upload errors
    try:
        await client.send_file('username', 'large_file.zip')
        
    except FileTooLargeError:
        print('File is too large (2GB limit)')
        
    except FilePartMissingError:
        print('File upload incomplete, retrying...')
        # Could implement retry logic here
        
    except MediaInvalidError:
        print('File format not supported')
    
    # Chat management errors
    try:
        await client.kick_participant('group_chat', 'user_to_kick')
        
    except ChatAdminRequiredError:
        print('Need admin privileges to kick users')
        
    except UserNotParticipantError:
        print('User is not in the chat')
        
    except UserBannedInChannelError:
        print('User is already banned')
    
    await client.disconnect()

Error Logging and Monitoring

import logging
from telethon.errors import RPCError

# Set up logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

async def monitored_operation(client, operation_name, operation_func, *args, **kwargs):
    """Execute operation with comprehensive error logging."""
    
    try:
        logger.info(f'Starting {operation_name}')
        result = await operation_func(*args, **kwargs)
        logger.info(f'Completed {operation_name} successfully')
        return result
        
    except FloodWaitError as e:
        logger.warning(f'{operation_name} rate limited: wait {e.seconds}s')
        raise
        
    except RPCError as e:
        logger.error(f'{operation_name} RPC error: {e.message} (code: {e.code})')
        logger.debug(f'Request that caused error: {e.request}')
        raise
        
    except Exception as e:
        logger.error(f'{operation_name} unexpected error: {e}')
        logger.exception('Full traceback:')
        raise

async def monitored_example():
    client = TelegramClient('session', api_id, api_hash)
    await client.start()
    
    # Monitor different operations
    await monitored_operation(
        client, 'send_message',
        client.send_message, 'username', 'Hello!'
    )
    
    await monitored_operation(
        client, 'get_participants',
        client.get_participants, 'group_chat'
    )
    
    await client.disconnect()

Custom Error Handler Context Manager

from contextlib import asynccontextmanager
from telethon.errors import FloodWaitError, RPCError

@asynccontextmanager
async def handle_telegram_errors(
    ignore_flood: bool = False,
    max_flood_wait: int = 300,
    retry_server_errors: bool = True
):
    """
    Context manager for common Telegram error handling patterns.
    
    Parameters:
    - ignore_flood: Whether to silently handle flood waits
    - max_flood_wait: Maximum seconds to wait for flood errors
    - retry_server_errors: Whether to retry on server errors
    """
    
    try:
        yield
        
    except FloodWaitError as e:
        if ignore_flood and e.seconds <= max_flood_wait:
            print(f'Waiting {e.seconds} seconds for rate limit...')
            await asyncio.sleep(e.seconds)
        else:
            print(f'Rate limited for {e.seconds} seconds')
            raise
            
    except RPCError as e:
        if e.code == 500 and retry_server_errors:
            print('Server error occurred, operation may need retry')
        
        # Log the error details
        print(f'Telegram error: {e.message} (code: {e.code})')
        raise
        
    except Exception as e:
        print(f'Unexpected error: {e}')
        raise

async def context_manager_example():
    client = TelegramClient('session', api_id, api_hash)
    await client.start()
    
    # Use context manager for error handling
    async with handle_telegram_errors(ignore_flood=True, max_flood_wait=60):
        await client.send_message('username', 'Protected message')
        
    async with handle_telegram_errors(retry_server_errors=False):
        participants = await client.get_participants('large_group')
        print(f'Got {len(participants)} participants')
    
    await client.disconnect()

Types

from typing import Optional, List, Any, Union
import asyncio

ErrorCode = int
ErrorMessage = str
WaitSeconds = int

class ErrorInfo:
    """Information about a Telegram error"""
    code: ErrorCode
    message: ErrorMessage
    request: Optional[Any]
    wait_time: Optional[WaitSeconds]

ErrorHandler = Union[
    Callable[[Exception], None],
    Callable[[Exception], Awaitable[None]]
]

RetryStrategy = Callable[[int, Exception], Union[bool, Awaitable[bool]]]

Install with Tessl CLI

npx tessl i tessl/pypi-telethon

docs

authentication-sessions.md

chat-management.md

client-management.md

error-handling.md

event-system.md

file-handling.md

index.md

message-operations.md

utilities-helpers.md

tile.json