CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-nextcord

A Python wrapper for the Discord API forked from discord.py

Pending
Overview
Eval results
Files

errors.mddocs/

Nextcord Errors

Exception hierarchy and error handling patterns for robust Discord bot development with comprehensive error management capabilities.

Exception Hierarchy

Core exception classes and their inheritance structure for handling various Discord API errors.

Base Exceptions { .api }

import nextcord
from nextcord import DiscordException, ClientException, HTTPException
from typing import Optional, Dict, Any, Union, List
import aiohttp

class DiscordException(Exception):
    """Base exception class for all nextcord exceptions.
    
    This is the root exception that all other nextcord exceptions inherit from.
    Catching this will catch all nextcord-specific errors.
    """
    pass

class ClientException(DiscordException):
    """Exception raised when an operation in the Client fails.
    
    These are usually user errors, such as providing invalid parameters
    or attempting operations that are not allowed.
    """
    pass

class HTTPException(DiscordException):
    """Exception raised when an HTTP request operation fails.
    
    Attributes
    ----------
    response: aiohttp.ClientResponse
        The aiohttp response object.
    status: int
        The HTTP status code.
    code: int
        The Discord error code.
    text: str
        The error message from Discord.
    """
    
    def __init__(self, response: aiohttp.ClientResponse, message: Optional[str]):
        self.response = response
        self.status = response.status
        self.code = 0
        self.text = message or ''
        
        if message:
            super().__init__(f'{self.status} {self.response.reason} (error code: {self.code}): {self.text}')
        else:
            super().__init__(f'{self.status} {self.response.reason}')

# Basic error handling example
@bot.event
async def on_command_error(ctx, error):
    """Global error handler for command errors."""
    
    if isinstance(error, nextcord.HTTPException):
        if error.status == 403:
            await ctx.send("❌ I don't have permission to do that!")
        elif error.status == 404:
            await ctx.send("❌ That resource was not found.")
        else:
            await ctx.send(f"❌ An HTTP error occurred: {error.text}")
    
    elif isinstance(error, nextcord.ClientException):
        await ctx.send(f"❌ Client error: {str(error)}")
    
    else:
        print(f"Unexpected error: {type(error).__name__}: {error}")
        await ctx.send("❌ An unexpected error occurred.")

# Specific exception handling
try:
    await channel.send("Hello!")
except nextcord.Forbidden:
    print("No permission to send messages to this channel")
except nextcord.HTTPException as e:
    print(f"HTTP error: {e.status} - {e.text}")
except nextcord.DiscordException:
    print("A Discord-related error occurred")

HTTP and API Errors

Specific HTTP exceptions for different Discord API error conditions.

HTTP Status Exceptions { .api }

class Forbidden(HTTPException):
    """Exception raised for 403 Forbidden HTTP responses.
    
    This typically means the bot lacks the necessary permissions
    to perform the requested action.
    """
    pass

class NotFound(HTTPException):
    """Exception raised for 404 Not Found HTTP responses.
    
    This means the requested resource (user, channel, message, etc.)
    does not exist or is not accessible.
    """
    pass

class DiscordServerError(HTTPException):
    """Exception raised for 5xx HTTP responses.
    
    These are server-side errors from Discord's API and are
    usually temporary.
    """
    pass

class RateLimited(HTTPException):
    """Exception raised when being rate limited by Discord.
    
    Attributes
    ----------
    retry_after: float
        Number of seconds to wait before retrying.
    """
    
    def __init__(self, response: aiohttp.ClientResponse, message: str, retry_after: float):
        super().__init__(response, message)
        self.retry_after = retry_after

# Comprehensive error handling
async def safe_send_message(channel, content, **kwargs):
    """Safely send a message with comprehensive error handling."""
    try:
        return await channel.send(content, **kwargs)
        
    except nextcord.Forbidden:
        print(f"No permission to send messages in {channel}")
        return None
        
    except nextcord.NotFound:
        print(f"Channel {channel.id} not found or deleted")
        return None
        
    except nextcord.RateLimited as e:
        print(f"Rate limited! Retry after {e.retry_after} seconds")
        await asyncio.sleep(e.retry_after)
        return await channel.send(content, **kwargs)  # Retry once
        
    except nextcord.HTTPException as e:
        print(f"HTTP error {e.status}: {e.text}")
        return None
        
    except Exception as e:
        print(f"Unexpected error: {type(e).__name__}: {e}")
        return None

# Guild-specific error handling
async def safe_add_role(member, role, reason=None):
    """Safely add a role to a member."""
    try:
        await member.add_roles(role, reason=reason)
        return True
        
    except nextcord.Forbidden:
        print(f"No permission to manage roles for {member}")
        return False
        
    except nextcord.NotFound:
        print(f"Member {member} or role {role} not found")
        return False
        
    except nextcord.HTTPException as e:
        if e.code == 50013:  # Missing permissions
            print(f"Missing permissions to add role {role.name}")
        elif e.code == 50025:  # Invalid OAuth2 access token
            print("Invalid bot token")
        else:
            print(f"Failed to add role: {e.text}")
        return False

# Message-related error handling
async def safe_edit_message(message, **kwargs):
    """Safely edit a message with error handling."""
    try:
        return await message.edit(**kwargs)
        
    except nextcord.Forbidden:
        print("No permission to edit this message")
        return None
        
    except nextcord.NotFound:
        print("Message not found (may have been deleted)")
        return None
        
    except nextcord.HTTPException as e:
        if e.code == 50005:  # Cannot edit message by another user
            print("Cannot edit message from another user")
        elif e.code == 50001:  # Missing access
            print("Missing access to edit message")
        else:
            print(f"Failed to edit message: {e.text}")
        return None

# Voice-related error handling
async def safe_connect_voice(channel):
    """Safely connect to a voice channel."""
    try:
        return await channel.connect()
        
    except nextcord.ClientException as e:
        if "already connected" in str(e).lower():
            print("Already connected to a voice channel")
            # Get existing connection
            return nextcord.utils.get(bot.voice_clients, guild=channel.guild)
        else:
            print(f"Client error connecting to voice: {e}")
            return None
            
    except nextcord.Forbidden:
        print(f"No permission to connect to {channel.name}")
        return None
        
    except asyncio.TimeoutError:
        print("Timeout connecting to voice channel")
        return None
        
    except Exception as e:
        print(f"Unexpected voice connection error: {e}")
        return None

Command Framework Errors

Errors specific to the command framework and command processing.

Command Exceptions { .api }

from nextcord.ext import commands

class CommandError(DiscordException):
    """Base exception for all command related errors.
    
    This inherits from DiscordException and is the base for all
    command framework exceptions.
    
    Attributes
    ----------
    message: Optional[str]
        The error message.
    """
    
    def __init__(self, message: Optional[str] = None, *args):
        if message is not None:
            super().__init__(message, *args)
        else:
            super().__init__(*args)

class CommandNotFound(CommandError):
    """Exception raised when a command is not found.
    
    This is raised when a user tries to invoke a command
    that doesn't exist.
    """
    pass

class MissingRequiredArgument(CommandError):
    """Exception raised when a required argument is missing.
    
    Attributes
    ----------
    param: inspect.Parameter
        The parameter that was missing.
    """
    
    def __init__(self, param):
        self.param = param
        super().__init__(f'{param.name} is a required argument that is missing.')

class BadArgument(CommandError):
    """Exception raised when parsing an argument fails.
    
    This is typically raised when a converter fails to convert
    the provided argument to the expected type.
    """
    pass

class CheckFailure(CommandError):
    """Exception raised when a check fails.
    
    This is raised when a command check (like permissions,
    cooldowns, etc.) fails.
    """
    pass

class MissingPermissions(CheckFailure):
    """Exception raised when the user lacks required permissions.
    
    Attributes
    ----------
    missing_perms: List[str]
        List of missing permission names.
    """
    
    def __init__(self, missing_perms: List[str], *args):
        self.missing_perms = missing_perms
        
        missing = [perm.replace('_', ' ').replace('guild', 'server').title() for perm in missing_perms]
        
        if len(missing) > 2:
            fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
        else:
            fmt = ' and '.join(missing)
        
        message = f'You are missing {fmt} permission(s) to run this command.'
        super().__init__(message, *args)

class BotMissingPermissions(CheckFailure):
    """Exception raised when the bot lacks required permissions.
    
    Attributes
    ----------
    missing_perms: List[str]
        List of missing permission names.
    """
    
    def __init__(self, missing_perms: List[str], *args):
        self.missing_perms = missing_perms
        
        missing = [perm.replace('_', ' ').replace('guild', 'server').title() for perm in missing_perms]
        
        if len(missing) > 2:
            fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
        else:
            fmt = ' and '.join(missing)
        
        message = f'Bot requires {fmt} permission(s) to run this command.'
        super().__init__(message, *args)

class CommandOnCooldown(CommandError):
    """Exception raised when a command is on cooldown.
    
    Attributes
    ----------
    cooldown: Cooldown
        The cooldown that was triggered.
    retry_after: float
        Number of seconds until the command can be used again.
    """
    
    def __init__(self, cooldown, retry_after: float):
        self.cooldown = cooldown
        self.retry_after = retry_after
        super().__init__(f'You are on cooldown. Try again in {retry_after:.2f}s')

# Command error handling examples
@bot.event
async def on_command_error(ctx: commands.Context, error: commands.CommandError):
    """Global command error handler."""
    
    # Ignore command not found errors
    if isinstance(error, commands.CommandNotFound):
        return
    
    # Handle missing arguments
    elif isinstance(error, commands.MissingRequiredArgument):
        embed = nextcord.Embed(
            title="❌ Missing Argument",
            description=f"Missing required argument: `{error.param.name}`",
            color=nextcord.Color.red()
        )
        embed.add_field(
            name="Usage",
            value=f"`{ctx.prefix}{ctx.command.qualified_name} {ctx.command.signature}`",
            inline=False
        )
        await ctx.send(embed=embed)
    
    # Handle bad arguments (conversion failures)
    elif isinstance(error, commands.BadArgument):
        embed = nextcord.Embed(
            title="❌ Invalid Argument",
            description=str(error),
            color=nextcord.Color.red()
        )
        await ctx.send(embed=embed)
    
    # Handle permission errors
    elif isinstance(error, commands.MissingPermissions):
        embed = nextcord.Embed(
            title="❌ Missing Permissions",
            description=str(error),
            color=nextcord.Color.red()
        )
        await ctx.send(embed=embed)
    
    elif isinstance(error, commands.BotMissingPermissions):
        embed = nextcord.Embed(
            title="❌ Bot Missing Permissions", 
            description=str(error),
            color=nextcord.Color.red()
        )
        await ctx.send(embed=embed)
    
    # Handle cooldowns
    elif isinstance(error, commands.CommandOnCooldown):
        embed = nextcord.Embed(
            title="⏰ Command on Cooldown",
            description=f"Please wait {error.retry_after:.1f} seconds before using this command again.",
            color=nextcord.Color.orange()
        )
        await ctx.send(embed=embed, delete_after=error.retry_after)
    
    # Handle other command errors
    elif isinstance(error, commands.CommandError):
        embed = nextcord.Embed(
            title="❌ Command Error",
            description=str(error),
            color=nextcord.Color.red()
        )
        await ctx.send(embed=embed)
    
    # Handle HTTP exceptions
    elif isinstance(error, nextcord.HTTPException):
        if error.status == 403:
            embed = nextcord.Embed(
                title="❌ Permission Denied",
                description="I don't have permission to perform that action.",
                color=nextcord.Color.red()
            )
        elif error.status == 404:
            embed = nextcord.Embed(
                title="❌ Not Found",
                description="The requested resource was not found.",
                color=nextcord.Color.red()
            )
        else:
            embed = nextcord.Embed(
                title="❌ HTTP Error",
                description=f"An error occurred: {error.text}",
                color=nextcord.Color.red()
            )
        await ctx.send(embed=embed)
    
    # Handle unexpected errors
    else:
        embed = nextcord.Embed(
            title="❌ Unexpected Error",
            description="An unexpected error occurred. Please try again later.",
            color=nextcord.Color.red()
        )
        await ctx.send(embed=embed)
        
        # Log the error for debugging
        print(f"Unexpected error in {ctx.command}: {type(error).__name__}: {error}")

# Command-specific error handling
@bot.command()
async def ban_user(ctx, member: nextcord.Member, *, reason: str = "No reason provided"):
    """Ban a user with proper error handling."""
    try:
        await member.ban(reason=reason)
        
        embed = nextcord.Embed(
            title="🔨 User Banned",
            description=f"{member.mention} has been banned.",
            color=nextcord.Color.red()
        )
        embed.add_field(name="Reason", value=reason, inline=False)
        embed.set_footer(text=f"Banned by {ctx.author}", icon_url=ctx.author.display_avatar.url)
        
        await ctx.send(embed=embed)
        
    except nextcord.Forbidden:
        await ctx.send("❌ I don't have permission to ban this user.")
    except nextcord.HTTPException as e:
        if e.code == 50013:  # Missing permissions
            await ctx.send("❌ I cannot ban this user (they may have higher permissions).")
        else:
            await ctx.send(f"❌ Failed to ban user: {e.text}")

# Converter error handling
class CustomMemberConverter(commands.Converter):
    """Custom member converter with detailed error messages."""
    
    async def convert(self, ctx: commands.Context, argument: str) -> nextcord.Member:
        try:
            # Try default member conversion
            return await commands.MemberConverter().convert(ctx, argument)
        except commands.MemberNotFound:
            # Provide helpful error message
            raise commands.BadArgument(
                f"Member '{argument}' not found. "
                "Try using their full username, nickname, or mention."
            )

@bot.command()
async def userinfo(ctx, member: CustomMemberConverter = None):
    """Get user info with custom converter error handling."""
    member = member or ctx.author
    
    embed = nextcord.Embed(title=f"User Info: {member}", color=member.color)
    embed.set_thumbnail(url=member.display_avatar.url)
    embed.add_field(name="ID", value=member.id, inline=True)
    embed.add_field(name="Joined", value=member.joined_at.strftime("%Y-%m-%d"), inline=True)
    
    await ctx.send(embed=embed)

Application Command Errors

Errors specific to slash commands and application commands.

Interaction Exceptions { .api }

class ApplicationCommandError(DiscordException):
    """Base exception for application command errors."""
    pass

class InteractionResponded(ClientException):
    """Exception raised when an interaction has already been responded to.
    
    This occurs when you try to respond to an interaction that has
    already received a response.
    """
    pass

class InteractionNotResponded(ClientException):
    """Exception raised when an interaction hasn't been responded to.
    
    This occurs when you try to edit or delete an interaction response
    that hasn't been sent yet.
    """
    pass

class InteractionTimedOut(ClientException):
    """Exception raised when an interaction times out.
    
    Interactions must be responded to within 3 seconds, or they will
    time out and become invalid.
    """
    pass

# Application command error handling
@bot.event
async def on_application_command_error(interaction: nextcord.Interaction, error: Exception):
    """Global application command error handler."""
    
    if isinstance(error, nextcord.ApplicationCommandError):
        # Handle application command specific errors
        await handle_app_command_error(interaction, error)
    
    elif isinstance(error, nextcord.InteractionResponded):
        print(f"Interaction {interaction.id} already responded to")
        return  # Can't send response since it's already responded
    
    elif isinstance(error, nextcord.InteractionNotResponded):
        try:
            embed = nextcord.Embed(
                title="❌ Command Error",
                description="An error occurred while processing your command.",
                color=nextcord.Color.red()
            )
            await interaction.response.send_message(embed=embed, ephemeral=True)
        except:
            print(f"Failed to respond to interaction {interaction.id}")
    
    elif isinstance(error, nextcord.Forbidden):
        try:
            embed = nextcord.Embed(
                title="❌ Permission Denied",
                description="I don't have permission to perform that action.",
                color=nextcord.Color.red()
            )
            
            if not interaction.response.is_done():
                await interaction.response.send_message(embed=embed, ephemeral=True)
            else:
                await interaction.followup.send(embed=embed, ephemeral=True)
        except:
            pass
    
    else:
        # Log unexpected errors
        print(f"Unexpected application command error: {type(error).__name__}: {error}")
        
        try:
            embed = nextcord.Embed(
                title="❌ Unexpected Error",
                description="An unexpected error occurred.",
                color=nextcord.Color.red()
            )
            
            if not interaction.response.is_done():
                await interaction.response.send_message(embed=embed, ephemeral=True)
            else:
                await interaction.followup.send(embed=embed, ephemeral=True)
        except:
            pass

async def handle_app_command_error(interaction: nextcord.Interaction, error: nextcord.ApplicationCommandError):
    """Handle application command specific errors."""
    
    embed = nextcord.Embed(
        title="❌ Command Error",
        description=str(error),
        color=nextcord.Color.red()
    )
    
    try:
        if not interaction.response.is_done():
            await interaction.response.send_message(embed=embed, ephemeral=True)
        else:
            await interaction.followup.send(embed=embed, ephemeral=True)
    except nextcord.InteractionResponded:
        # Already responded, try followup
        try:
            await interaction.followup.send(embed=embed, ephemeral=True)
        except:
            pass

# Safe interaction response helper
async def safe_interaction_response(
    interaction: nextcord.Interaction,
    content: str = None,
    embed: nextcord.Embed = None,
    ephemeral: bool = False,
    **kwargs
):
    """Safely respond to an interaction with error handling."""
    try:
        if not interaction.response.is_done():
            await interaction.response.send_message(
                content=content,
                embed=embed,
                ephemeral=ephemeral,
                **kwargs
            )
        else:
            await interaction.followup.send(
                content=content,
                embed=embed,
                ephemeral=ephemeral,
                **kwargs
            )
        return True
        
    except nextcord.InteractionResponded:
        print(f"Interaction {interaction.id} already responded to")
        return False
        
    except nextcord.InteractionTimedOut:
        print(f"Interaction {interaction.id} timed out")
        return False
        
    except nextcord.HTTPException as e:
        print(f"HTTP error responding to interaction: {e.status} - {e.text}")
        return False
        
    except Exception as e:
        print(f"Unexpected error responding to interaction: {e}")
        return False

# Slash command with comprehensive error handling
@bot.slash_command(description="Kick a member from the server")
async def kick_member(
    interaction: nextcord.Interaction,
    member: nextcord.Member,
    reason: str = "No reason provided"
):
    """Kick command with proper error handling."""
    
    # Check permissions
    if not interaction.user.guild_permissions.kick_members:
        embed = nextcord.Embed(
            title="❌ Missing Permissions",
            description="You need 'Kick Members' permission to use this command.",
            color=nextcord.Color.red()
        )
        await safe_interaction_response(interaction, embed=embed, ephemeral=True)
        return
    
    # Check if bot can kick the member
    if member.top_role >= interaction.guild.me.top_role:
        embed = nextcord.Embed(
            title="❌ Cannot Kick",
            description="I cannot kick this member (they have equal or higher role).",
            color=nextcord.Color.red()
        )
        await safe_interaction_response(interaction, embed=embed, ephemeral=True)
        return
    
    # Check if user can kick the member
    if member.top_role >= interaction.user.top_role and interaction.user != interaction.guild.owner:
        embed = nextcord.Embed(
            title="❌ Cannot Kick",
            description="You cannot kick this member (they have equal or higher role).",
            color=nextcord.Color.red()
        )
        await safe_interaction_response(interaction, embed=embed, ephemeral=True)
        return
    
    try:
        # Attempt to kick the member
        await member.kick(reason=f"{reason} | Kicked by {interaction.user}")
        
        embed = nextcord.Embed(
            title="👢 Member Kicked",
            description=f"{member.mention} has been kicked from the server.",
            color=nextcord.Color.orange()
        )
        embed.add_field(name="Reason", value=reason, inline=False)
        embed.set_footer(text=f"Kicked by {interaction.user}", icon_url=interaction.user.display_avatar.url)
        
        await safe_interaction_response(interaction, embed=embed)
        
    except nextcord.Forbidden:
        embed = nextcord.Embed(
            title="❌ Permission Denied",
            description="I don't have permission to kick this member.",
            color=nextcord.Color.red()
        )
        await safe_interaction_response(interaction, embed=embed, ephemeral=True)
        
    except nextcord.HTTPException as e:
        embed = nextcord.Embed(
            title="❌ Kick Failed",
            description=f"Failed to kick member: {e.text}",
            color=nextcord.Color.red()
        )
        await safe_interaction_response(interaction, embed=embed, ephemeral=True)

Custom Error Classes

Creating custom exceptions for specific bot functionality and domain-specific errors.

Custom Exception Implementation { .api }

# Custom bot-specific exceptions
class BotException(DiscordException):
    """Base exception for custom bot errors."""
    pass

class DatabaseError(BotException):
    """Exception raised when database operations fail.
    
    Attributes
    ----------
    operation: str
        The database operation that failed.
    table: Optional[str]
        The table involved in the operation.
    """
    
    def __init__(self, operation: str, table: Optional[str] = None, message: Optional[str] = None):
        self.operation = operation
        self.table = table
        
        if message:
            super().__init__(message)
        else:
            msg = f"Database {operation} failed"
            if table:
                msg += f" on table '{table}'"
            super().__init__(msg)

class ConfigurationError(BotException):
    """Exception raised for configuration-related errors.
    
    Attributes
    ----------
    setting: str
        The configuration setting that caused the error.
    """
    
    def __init__(self, setting: str, message: Optional[str] = None):
        self.setting = setting
        super().__init__(message or f"Configuration error for setting '{setting}'")

class RateLimitExceeded(BotException):
    """Exception raised when custom rate limits are exceeded.
    
    Attributes
    ----------
    user_id: int
        The user who exceeded the rate limit.
    command: str
        The command that was rate limited.
    retry_after: float
        Seconds until the user can retry.
    """
    
    def __init__(self, user_id: int, command: str, retry_after: float):
        self.user_id = user_id
        self.command = command
        self.retry_after = retry_after
        super().__init__(f"Rate limit exceeded for {command}. Try again in {retry_after:.1f}s")

class InsufficientBalance(BotException):
    """Exception raised when a user has insufficient balance for an operation.
    
    Attributes
    ----------
    user_id: int
        The user's ID.
    required: int
        The required amount.
    available: int
        The available amount.
    """
    
    def __init__(self, user_id: int, required: int, available: int):
        self.user_id = user_id
        self.required = required
        self.available = available
        super().__init__(f"Insufficient balance. Required: {required}, Available: {available}")

class ItemNotFound(BotException):
    """Exception raised when a requested item is not found.
    
    Attributes
    ----------
    item_type: str
        The type of item (e.g., 'user', 'guild', 'item').
    item_id: Union[int, str]
        The ID or name of the item.
    """
    
    def __init__(self, item_type: str, item_id: Union[int, str]):
        self.item_type = item_type
        self.item_id = item_id
        super().__init__(f"{item_type.title()} '{item_id}' not found")

# Custom error handler for bot-specific errors
class BotErrorHandler:
    """Centralized error handler for custom bot errors."""
    
    def __init__(self, bot):
        self.bot = bot
        self.error_log_channel = None
    
    def set_error_log_channel(self, channel_id: int):
        """Set the channel where errors should be logged."""
        self.error_log_channel = channel_id
    
    async def handle_error(
        self,
        error: Exception,
        ctx: Optional[commands.Context] = None,
        interaction: Optional[nextcord.Interaction] = None,
        user: Optional[nextcord.User] = None
    ):
        """Handle different types of errors with appropriate responses."""
        
        # Determine response method
        if ctx:
            respond = lambda **kwargs: ctx.send(**kwargs)
        elif interaction:
            respond = lambda **kwargs: safe_interaction_response(interaction, **kwargs)
        else:
            respond = None
        
        # Handle custom errors
        if isinstance(error, DatabaseError):
            await self._handle_database_error(error, respond)
        
        elif isinstance(error, ConfigurationError):
            await self._handle_config_error(error, respond)
        
        elif isinstance(error, RateLimitExceeded):
            await self._handle_rate_limit_error(error, respond)
        
        elif isinstance(error, InsufficientBalance):
            await self._handle_balance_error(error, respond)
        
        elif isinstance(error, ItemNotFound):
            await self._handle_not_found_error(error, respond)
        
        # Handle Discord errors
        elif isinstance(error, nextcord.Forbidden):
            await self._handle_forbidden_error(error, respond)
        
        elif isinstance(error, nextcord.NotFound):
            await self._handle_not_found_discord_error(error, respond)
        
        else:
            await self._handle_unexpected_error(error, respond, ctx, interaction)
    
    async def _handle_database_error(self, error: DatabaseError, respond):
        """Handle database errors."""
        embed = nextcord.Embed(
            title="🗃️ Database Error",
            description="A database error occurred. Please try again later.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
        
        # Log to error channel
        await self._log_error("Database Error", str(error))
    
    async def _handle_config_error(self, error: ConfigurationError, respond):
        """Handle configuration errors."""
        embed = nextcord.Embed(
            title="⚙️ Configuration Error",
            description="A configuration issue was detected. Please contact an administrator.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
        
        await self._log_error("Configuration Error", f"Setting: {error.setting} - {str(error)}")
    
    async def _handle_rate_limit_error(self, error: RateLimitExceeded, respond):
        """Handle custom rate limit errors."""
        embed = nextcord.Embed(
            title="⏰ Rate Limited",
            description=f"You're using commands too quickly! Please wait {error.retry_after:.1f} seconds.",
            color=nextcord.Color.orange()
        )
        
        if respond:
            await respond(embed=embed)
    
    async def _handle_balance_error(self, error: InsufficientBalance, respond):
        """Handle insufficient balance errors."""
        embed = nextcord.Embed(
            title="💰 Insufficient Balance",
            description=f"You need {error.required} but only have {error.available}.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
    
    async def _handle_not_found_error(self, error: ItemNotFound, respond):
        """Handle item not found errors."""
        embed = nextcord.Embed(
            title="❓ Not Found",
            description=f"{error.item_type.title()} '{error.item_id}' was not found.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
    
    async def _handle_forbidden_error(self, error: nextcord.Forbidden, respond):
        """Handle Discord forbidden errors."""
        embed = nextcord.Embed(
            title="❌ Permission Denied",
            description="I don't have permission to perform that action.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
    
    async def _handle_not_found_discord_error(self, error: nextcord.NotFound, respond):
        """Handle Discord not found errors."""
        embed = nextcord.Embed(
            title="❓ Resource Not Found",
            description="The requested Discord resource was not found.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
    
    async def _handle_unexpected_error(
        self,
        error: Exception,
        respond,
        ctx: Optional[commands.Context],
        interaction: Optional[nextcord.Interaction]
    ):
        """Handle unexpected errors."""
        embed = nextcord.Embed(
            title="❌ Unexpected Error",
            description="An unexpected error occurred. The developers have been notified.",
            color=nextcord.Color.red()
        )
        
        if respond:
            await respond(embed=embed)
        
        # Log detailed error information
        error_info = {
            'type': type(error).__name__,
            'message': str(error),
            'command': ctx.command.name if ctx else None,
            'interaction': interaction.data.get('name') if interaction else None,
            'user': (ctx.author.id if ctx else interaction.user.id if interaction else None),
            'guild': (ctx.guild.id if ctx and ctx.guild else interaction.guild.id if interaction and interaction.guild else None)
        }
        
        await self._log_error("Unexpected Error", str(error_info))
    
    async def _log_error(self, title: str, description: str):
        """Log error to designated channel."""
        if not self.error_log_channel:
            return
        
        channel = self.bot.get_channel(self.error_log_channel)
        if not channel:
            return
        
        embed = nextcord.Embed(
            title=f"🚨 {title}",
            description=f"```\n{description}\n```",
            color=nextcord.Color.red(),
            timestamp=datetime.now()
        )
        
        try:
            await channel.send(embed=embed)
        except:
            pass  # Silently fail if we can't log

# Initialize error handler
error_handler = BotErrorHandler(bot)
error_handler.set_error_log_channel(ERROR_LOG_CHANNEL_ID)

# Usage in commands
@bot.command()
async def buy_item(ctx, item_name: str):
    """Buy an item with comprehensive error handling."""
    try:
        # Get user data
        user_data = await get_user_data(ctx.author.id)
        if not user_data:
            raise ItemNotFound("user", ctx.author.id)
        
        # Get item data
        item = await get_item_by_name(item_name)
        if not item:
            raise ItemNotFound("item", item_name)
        
        # Check balance
        if user_data['balance'] < item['price']:
            raise InsufficientBalance(ctx.author.id, item['price'], user_data['balance'])
        
        # Process purchase
        await process_purchase(ctx.author.id, item['id'])
        
        embed = nextcord.Embed(
            title="🛒 Purchase Successful",
            description=f"You bought {item['name']} for {item['price']} coins!",
            color=nextcord.Color.green()
        )
        await ctx.send(embed=embed)
        
    except BotException as e:
        # Handle custom bot errors
        await error_handler.handle_error(e, ctx=ctx)
        
    except Exception as e:
        # Handle unexpected errors
        await error_handler.handle_error(e, ctx=ctx)

# Global error handlers using the error handler
@bot.event
async def on_command_error(ctx: commands.Context, error: commands.CommandError):
    """Enhanced global command error handler."""
    await error_handler.handle_error(error, ctx=ctx)

@bot.event
async def on_application_command_error(interaction: nextcord.Interaction, error: Exception):
    """Enhanced application command error handler."""
    await error_handler.handle_error(error, interaction=interaction)

This comprehensive documentation covers all aspects of nextcord's error handling system, providing developers with robust tools for managing exceptions and creating reliable Discord bot applications with proper error recovery mechanisms.

Install with Tessl CLI

npx tessl i tessl/pypi-nextcord

docs

application-commands.md

channels.md

client.md

commands.md

errors.md

events.md

guild.md

index.md

messages.md

permissions.md

tasks.md

ui.md

users.md

utilities.md

voice.md

webhooks.md

tile.json