CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pypresence

Discord RPC client written in Python for integrating applications with Discord's Rich Presence system

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

Comprehensive exception hierarchy for handling Discord integration errors. Pypresence provides specific exceptions for different failure scenarios, enabling precise error handling and debugging.

Capabilities

Base Exception

class PyPresenceException(Exception):
    def __init__(self, message: str = None):
        """
        Base exception for all pypresence errors.
        
        Parameters:
        - message (str): Optional custom error message
        """

Connection Exceptions

class DiscordNotFound(PyPresenceException):
    def __init__(self):
        """
        Raised when Discord is not installed or not running.
        
        This exception indicates that the Discord client could not be found
        on the system or is not currently running.
        """
class InvalidPipe(PyPresenceException):
    def __init__(self):
        """
        Raised when the Discord IPC pipe cannot be found.
        
        This typically occurs when Discord is not running or the IPC
        communication channels are not available.
        """
class ConnectionTimeout(PyPresenceException):
    def __init__(self):
        """
        Raised when unable to create a connection to the pipe in time.
        
        This occurs when the connection attempt exceeds the specified
        connection_timeout value.
        """
class PipeClosed(PyPresenceException):
    def __init__(self):
        """
        Raised when the Discord IPC pipe is closed unexpectedly.
        
        This can occur when Discord is closed while maintaining an active
        connection. Applications should catch this and attempt to reconnect.
        """

Communication Exceptions

class ResponseTimeout(PyPresenceException):
    def __init__(self):
        """
        Raised when no response is received from Discord RPC in time.
        
        This occurs when Discord doesn't respond within the specified
        response_timeout value.
        """
class ServerError(PyPresenceException):
    def __init__(self, message: str):
        """
        Raised when Discord server returns an error.
        
        Parameters:
        - message (str): Error message from Discord server
        """

Discord API Exceptions

class DiscordError(PyPresenceException):
    def __init__(self, code: int, message: str, override: bool = False):
        """
        Raised when Discord API returns an error response.
        
        Parameters:
        - code (int): Discord error code
        - message (str): Error message from Discord
        - override (bool): Whether to use message as-is
        
        Attributes:
        - code (int): Discord error code
        - message (str): Original error message
        """
class InvalidID(DiscordError):
    def __init__(self):
        """
        Raised when the Discord application client ID is invalid.
        
        This occurs when the provided client_id doesn't match any
        registered Discord application.
        """

Parameter Validation Exceptions

class InvalidArgument(PyPresenceException):
    def __init__(self, expected, received, description: str = None):
        """
        Raised when invalid arguments are passed to functions.
        
        Parameters:
        - expected: Expected argument type or value
        - received: Actual argument type or value received
        - description (str): Optional additional description
        """
class ArgumentError(PyPresenceException):
    def __init__(self):
        """
        Raised when function arguments are incorrect.
        
        Typically occurs when event handler functions don't have
        the correct number of parameters.
        """

Event Management Exceptions

class EventNotFound(PyPresenceException):
    def __init__(self, event: str):
        """
        Raised when trying to unregister a non-existent event.
        
        Parameters:
        - event (str): Name of the event that wasn't found
        """

Exception Hierarchy

PyPresenceException (base)
├── DiscordNotFound
├── InvalidPipe
├── ConnectionTimeout
├── PipeClosed
├── ResponseTimeout
├── ServerError
├── InvalidArgument
├── ArgumentError
├── EventNotFound
└── DiscordError
    └── InvalidID

Usage Examples

Basic Error Handling

from pypresence import Presence
from pypresence import (
    DiscordNotFound, InvalidPipe, PipeClosed, 
    ResponseTimeout, InvalidID
)

def connect_with_retry(client_id, max_retries=3):
    for attempt in range(max_retries):
        try:
            RPC = Presence(client_id)
            RPC.connect()
            return RPC
        except DiscordNotFound:
            print("Discord is not running. Please start Discord.")
            return None
        except InvalidID:
            print("Invalid client ID. Check your Discord application settings.")
            return None
        except (InvalidPipe, ConnectionTimeout) as e:
            print(f"Connection failed (attempt {attempt + 1}): {e}")
            if attempt == max_retries - 1:
                print("Max retries reached. Unable to connect.")
                return None
            time.sleep(2)  # Wait before retry
    
    return None

Comprehensive Error Handling

from pypresence import Presence, PyPresenceException
import time
import logging

def robust_presence_client(client_id):
    RPC = None
    
    try:
        # Initialize client
        RPC = Presence(client_id, connection_timeout=10, response_timeout=5)
        RPC.connect()
        
        while True:
            try:
                # Update presence
                RPC.update(
                    state="Online",
                    details="Available for chat",
                    large_image="status_online"
                )
                time.sleep(15)
                
            except PipeClosed:
                logging.warning("Discord connection lost. Attempting to reconnect...")
                try:
                    RPC.connect()
                    logging.info("Reconnected successfully.")
                except PyPresenceException as e:
                    logging.error(f"Reconnection failed: {e}")
                    break
                    
            except ResponseTimeout:
                logging.warning("Discord not responding. Continuing...")
                continue
                
            except Exception as e:
                logging.error(f"Unexpected error: {e}")
                break
                
    except DiscordNotFound:
        logging.error("Discord is not running. Please start Discord and try again.")
    except InvalidID:
        logging.error("Invalid client ID. Check your Discord application configuration.")
    except ConnectionTimeout:
        logging.error("Connection timeout. Discord may be unresponsive.")
    except PyPresenceException as e:
        logging.error(f"PyPresence error: {e}")
    except Exception as e:
        logging.error(f"Unexpected error: {e}")
    finally:
        if RPC:
            try:
                RPC.close()
            except:
                pass  # Ignore errors during cleanup

# Usage
robust_presence_client("your_client_id")

Event Handler Error Handling

from pypresence import Client, ArgumentError, EventNotFound

def safe_event_handler(data):
    """Event handler that won't crash the application."""
    try:
        print(f"Received event data: {data}")
        # Process event data here
    except Exception as e:
        print(f"Error in event handler: {e}")

def setup_events(client):
    try:
        # Register event with proper signature
        client.register_event("ACTIVITY_JOIN", safe_event_handler)
        
        # This would raise ArgumentError - wrong number of parameters
        # client.register_event("ACTIVITY_JOIN", lambda: print("Invalid"))
        
    except ArgumentError:
        print("Event handler must accept exactly one parameter.")
    except Exception as e:
        print(f"Failed to register event: {e}")

def cleanup_events(client):
    try:
        client.unregister_event("ACTIVITY_JOIN")
    except EventNotFound:
        print("Event was not registered.")
    except Exception as e:
        print(f"Error unregistering event: {e}")

Async Error Handling

import asyncio
from pypresence import AioPresence, PyPresenceException

async def async_presence_with_error_handling(client_id):
    RPC = None
    
    try:
        RPC = AioPresence(client_id)
        await RPC.connect()
        
        # Set initial presence
        await RPC.update(
            state="Starting up",
            details="Initializing application"
        )
        
        # Simulate long-running application
        for i in range(100):
            try:
                await RPC.update(
                    state=f"Running - Step {i+1}",
                    details="Processing data"
                )
                await asyncio.sleep(10)
                
            except PyPresenceException as e:
                print(f"Presence update failed: {e}")
                # Continue running even if presence update fails
                continue
                
    except PyPresenceException as e:
        print(f"Failed to initialize Discord presence: {e}")
    finally:
        if RPC:
            RPC.close()

# Run with error handling
asyncio.run(async_presence_with_error_handling("your_client_id"))

Custom Error Handling

from pypresence import Presence, PyPresenceException

class PresenceManager:
    def __init__(self, client_id, auto_retry=True):
        self.client_id = client_id
        self.auto_retry = auto_retry
        self.RPC = None
        self._connected = False
    
    def connect(self):
        """Connect with custom error handling."""
        try:
            self.RPC = Presence(self.client_id)
            self.RPC.connect()
            self._connected = True
            return True
        except PyPresenceException as e:
            self._handle_error(e)
            return False
    
    def update_safe(self, **kwargs):
        """Update presence with automatic error recovery."""
        if not self._connected and self.auto_retry:
            if not self.connect():
                return False
        
        try:
            self.RPC.update(**kwargs)
            return True
        except PyPresenceException as e:
            self._handle_error(e)
            if self.auto_retry and isinstance(e, (PipeClosed, ResponseTimeout)):
                self._connected = False
                return self.update_safe(**kwargs)  # Retry once
            return False
    
    def _handle_error(self, error):
        """Custom error handling logic."""
        error_actions = {
            DiscordNotFound: "Please start Discord and try again.",
            InvalidID: "Check your Discord application client ID.",
            PipeClosed: "Discord connection lost. Will attempt to reconnect.",
            ResponseTimeout: "Discord is not responding. Retrying...",
        }
        
        action = error_actions.get(type(error), f"Unknown error: {error}")
        print(f"Discord error: {action}")
    
    def close(self):
        """Clean shutdown."""
        if self.RPC:
            self.RPC.close()
            self._connected = False

# Usage
manager = PresenceManager("your_client_id", auto_retry=True)
if manager.connect():
    manager.update_safe(state="Connected", details="Ready to go!")

Install with Tessl CLI

npx tessl i tessl/pypi-pypresence

docs

discord-rpc-client.md

exceptions.md

index.md

rich-presence.md

tile.json