A modern, async-ready Python API wrapper for Discord with comprehensive bot development features
Overall
score
93%
Comprehensive exception hierarchy for handling Discord API errors, connection issues, command errors, and other failure scenarios. This system provides detailed error information and proper exception handling patterns for robust Discord bot development.
Base exception classes for Discord-related errors and API failures.
class DiscordException(Exception):
"""
Base exception class for Discord-related errors.
All discord.py exceptions inherit from this class.
"""
pass
class ClientException(DiscordException):
"""
Exception raised for client-side errors.
These are errors caused by incorrect usage of the library
rather than Discord API issues.
"""
pass
class NoMoreItems(DiscordException):
"""
Exception raised when an async iterator has no more items.
"""
pass
class GatewayNotFound(DiscordException):
"""
Exception raised when the Discord gateway endpoint is not found.
"""
pass
class ConnectionClosed(DiscordException):
"""
Exception raised when the gateway connection is closed unexpectedly.
"""
def __init__(self, original: Exception, shard_id: Optional[int] = None) -> None:
"""
Initialize connection closed exception.
Parameters:
- original: Exception - The original exception that caused the closure
- shard_id: int - ID of the shard that disconnected
"""
@property
def code(self) -> int:
"""The WebSocket close code."""
@property
def reason(self) -> str:
"""The reason for the connection closure."""
@property
def shard_id(self) -> Optional[int]:
"""The shard ID that disconnected."""
class PrivilegedIntentsRequired(ClientException):
"""
Exception raised when privileged intents are required but not enabled.
This occurs when trying to access features that require privileged intents
(message content, members, presences) without having them enabled.
"""
def __init__(self, shard_id: Optional[int] = None) -> None: ...
@property
def shard_id(self) -> Optional[int]: ...
class LoginFailure(DiscordException):
"""
Exception raised when bot login fails.
Usually caused by invalid bot token.
"""
passExceptions related to Discord's REST API and HTTP requests.
class HTTPException(DiscordException):
"""
Base exception for HTTP-related errors with Discord's API.
"""
def __init__(
self,
response: aiohttp.ClientResponse,
message: Union[str, Dict[str, Any]]
) -> None: ...
@property
def response(self) -> aiohttp.ClientResponse:
"""The HTTP response that caused the exception."""
@property
def status(self) -> int:
"""HTTP status code."""
@property
def code(self) -> int:
"""Discord API error code."""
@property
def text(self) -> str:
"""Error message text."""
class Forbidden(HTTPException):
"""
Exception raised for 403 Forbidden HTTP responses.
Indicates insufficient permissions for the requested action.
"""
pass
class NotFound(HTTPException):
"""
Exception raised for 404 Not Found HTTP responses.
Indicates the requested resource doesn't exist.
"""
pass
class DiscordServerError(HTTPException):
"""
Exception raised for 5xx server error HTTP responses.
Indicates an error on Discord's side.
"""
pass
class InvalidData(DiscordException):
"""
Exception raised when Discord sends invalid or unexpected data.
"""
pass
class InvalidArgument(DiscordException):
"""
Exception raised when an invalid argument is passed to a function.
"""
pass
class ValidationError(DiscordException):
"""
Exception raised when data validation fails.
"""
passExceptions related to loading and managing bot extensions and cogs.
class ExtensionError(DiscordException):
"""
Base exception for extension-related errors.
"""
def __init__(self, message: str = None, *, name: str) -> None:
"""
Initialize extension error.
Parameters:
- message: str - Error message
- name: str - Extension name that caused the error
"""
@property
def name(self) -> str:
"""The name of the extension that caused the error."""
class ExtensionAlreadyLoaded(ExtensionError):
"""
Exception raised when trying to load an already loaded extension.
"""
pass
class ExtensionNotLoaded(ExtensionError):
"""
Exception raised when trying to reload/unload an extension that isn't loaded.
"""
pass
class NoEntryPointError(ExtensionError):
"""
Exception raised when an extension doesn't have a setup function.
Extensions must have either a 'setup' function or a 'Cog' class.
"""
pass
class ExtensionFailed(ExtensionError):
"""
Exception raised when an extension fails to load due to an error.
"""
def __init__(
self,
name: str,
original: Exception
) -> None:
"""
Initialize extension failed error.
Parameters:
- name: str - Extension name
- original: Exception - The original exception that caused the failure
"""
@property
def original(self) -> Exception:
"""The original exception that caused the extension to fail."""
class ExtensionNotFound(ExtensionError):
"""
Exception raised when an extension file cannot be found.
"""
passExceptions specific to application commands (slash commands, context menus).
class ApplicationCommandError(DiscordException):
"""
Base exception for application command errors.
"""
pass
class ApplicationCommandInvokeError(ApplicationCommandError):
"""
Exception raised when an application command raises an unhandled error.
"""
def __init__(self, command: ApplicationCommand, original: Exception) -> None:
"""
Initialize command invoke error.
Parameters:
- command: ApplicationCommand - The command that failed
- original: Exception - The original exception
"""
@property
def command(self) -> ApplicationCommand:
"""The command that caused the error."""
@property
def original(self) -> Exception:
"""The original exception that was raised."""
class CheckFailure(ApplicationCommandError):
"""
Exception raised when an application command check fails.
"""
pass
class InteractionResponded(ApplicationCommandError):
"""
Exception raised when trying to respond to an already responded interaction.
"""
def __init__(self, interaction: Interaction) -> None: ...
@property
def interaction(self) -> Interaction: ...Extensive exception system for the commands extension framework.
# Base Command Errors
class CommandError(DiscordException):
"""
Base exception for command-related errors in the commands extension.
"""
def __init__(self, message: str = None, *args) -> None: ...
class UserInputError(CommandError):
"""
Base exception for errors caused by user input.
"""
pass
class CommandNotFound(CommandError):
"""
Exception raised when a command is not found.
"""
pass
class MissingRequiredArgument(UserInputError):
"""
Exception raised when a required command argument is missing.
"""
def __init__(self, param: inspect.Parameter) -> None:
"""
Initialize missing argument error.
Parameters:
- param: Parameter - The missing parameter
"""
@property
def param(self) -> inspect.Parameter:
"""The missing parameter."""
class TooManyArguments(UserInputError):
"""
Exception raised when too many arguments are provided to a command.
"""
pass
class BadArgument(UserInputError):
"""
Exception raised when argument conversion fails.
"""
pass
class ArgumentParsingError(UserInputError):
"""
Exception raised when argument parsing fails.
"""
pass
class UnexpectedQuoteError(ArgumentParsingError):
"""
Exception raised when an unexpected quote character is found.
"""
def __init__(self, quote: str) -> None: ...
@property
def quote(self) -> str: ...
class InvalidEndOfQuotedStringError(ArgumentParsingError):
"""
Exception raised when a quoted string doesn't end properly.
"""
def __init__(self, char: str) -> None: ...
@property
def char(self) -> str: ...
class ExpectedClosingQuoteError(ArgumentParsingError):
"""
Exception raised when a closing quote is expected but not found.
"""
def __init__(self, close_quote: str) -> None: ...
@property
def close_quote(self) -> str: ...
# Check Failures
class CheckFailure(CommandError):
"""
Exception raised when a command check fails.
"""
pass
class CheckAnyFailure(CheckFailure):
"""
Exception raised when all checks in a check_any decorator fail.
"""
def __init__(self, checks: List[Callable], errors: List[CheckFailure]) -> None: ...
@property
def checks(self) -> List[Callable]: ...
@property
def errors(self) -> List[CheckFailure]: ...
class PrivateMessageOnly(CheckFailure):
"""
Exception raised when a command can only be used in private messages.
"""
pass
class NoPrivateMessage(CheckFailure):
"""
Exception raised when a command cannot be used in private messages.
"""
pass
class NotOwner(CheckFailure):
"""
Exception raised when a command requires the user to be the bot owner.
"""
pass
class MissingRole(CheckFailure):
"""
Exception raised when a user is missing a required role.
"""
def __init__(self, missing_role: Union[str, int]) -> None: ...
@property
def missing_role(self) -> Union[str, int]: ...
class BotMissingRole(CheckFailure):
"""
Exception raised when the bot is missing a required role.
"""
def __init__(self, missing_role: Union[str, int]) -> None: ...
@property
def missing_role(self) -> Union[str, int]: ...
class MissingAnyRole(CheckFailure):
"""
Exception raised when a user is missing all required roles.
"""
def __init__(self, missing_roles: List[Union[str, int]]) -> None: ...
@property
def missing_roles(self) -> List[Union[str, int]]: ...
class BotMissingAnyRole(CheckFailure):
"""
Exception raised when the bot is missing all required roles.
"""
def __init__(self, missing_roles: List[Union[str, int]]) -> None: ...
@property
def missing_roles(self) -> List[Union[str, int]]: ...
class MissingPermissions(CheckFailure):
"""
Exception raised when a user is missing required permissions.
"""
def __init__(self, missing_permissions: List[str], *args) -> None: ...
@property
def missing_permissions(self) -> List[str]: ...
class BotMissingPermissions(CheckFailure):
"""
Exception raised when the bot is missing required permissions.
"""
def __init__(self, missing_permissions: List[str], *args) -> None: ...
@property
def missing_permissions(self) -> List[str]: ...
class NSFWChannelRequired(CheckFailure):
"""
Exception raised when a command requires an NSFW channel.
"""
def __init__(self, channel: GuildChannel) -> None: ...
@property
def channel(self) -> GuildChannel: ...
# Command Execution Errors
class DisabledCommand(CommandError):
"""
Exception raised when a disabled command is invoked.
"""
pass
class CommandInvokeError(CommandError):
"""
Exception raised when a command raises an unhandled exception.
"""
def __init__(self, command: Command, original: Exception) -> None: ...
@property
def command(self) -> Command: ...
@property
def original(self) -> Exception: ...
class CommandOnCooldown(CommandError):
"""
Exception raised when a command is on cooldown.
"""
def __init__(
self,
cooldown: Cooldown,
retry_after: float,
type: BucketType
) -> None: ...
@property
def cooldown(self) -> Cooldown: ...
@property
def retry_after(self) -> float: ...
@property
def type(self) -> BucketType: ...
class MaxConcurrencyReached(CommandError):
"""
Exception raised when a command's max concurrency is reached.
"""
def __init__(self, number: int, per: BucketType) -> None: ...
@property
def number(self) -> int: ...
@property
def per(self) -> BucketType: ...
# Conversion Errors
class ConversionError(CommandError):
"""
Base exception for argument conversion errors.
"""
def __init__(self, converter: Any, original: Exception) -> None: ...
@property
def converter(self) -> Any: ...
@property
def original(self) -> Exception: ...
class BadUnionArgument(UserInputError):
"""
Exception raised when a Union converter fails.
"""
def __init__(
self,
param: inspect.Parameter,
converters: Tuple[Type, ...],
errors: List[CommandError]
) -> None: ...
@property
def param(self) -> inspect.Parameter: ...
@property
def converters(self) -> Tuple[Type, ...]: ...
@property
def errors(self) -> List[CommandError]: ...
class BadLiteralArgument(UserInputError):
"""
Exception raised when a Literal converter fails.
"""
def __init__(
self,
param: inspect.Parameter,
literals: Tuple[Any, ...],
argument: str
) -> None: ...
@property
def param(self) -> inspect.Parameter: ...
@property
def literals(self) -> Tuple[Any, ...]: ...
@property
def argument(self) -> str: ...
class BadBoolArgument(BadArgument):
"""
Exception raised when a boolean conversion fails.
"""
def __init__(self, argument: str) -> None: ...
@property
def argument(self) -> str: ...
class BadColourArgument(BadArgument):
"""
Exception raised when a Colour conversion fails.
"""
def __init__(self, argument: str) -> None: ...
@property
def argument(self) -> str: ...
class BadColorArgument(BadColourArgument):
"""
Alias for BadColourArgument using American spelling.
"""
pass
class BadInviteArgument(BadArgument):
"""
Exception raised when an Invite conversion fails.
"""
pass
# Object Not Found Errors
class ObjectNotFound(BadArgument):
"""
Base exception for when a Discord object is not found.
"""
def __init__(self, argument: str) -> None: ...
@property
def argument(self) -> str: ...
class MessageNotFound(ObjectNotFound):
"""
Exception raised when a Message is not found.
"""
pass
class MemberNotFound(ObjectNotFound):
"""
Exception raised when a Member is not found.
"""
pass
class GuildNotFound(ObjectNotFound):
"""
Exception raised when a Guild is not found.
"""
pass
class UserNotFound(ObjectNotFound):
"""
Exception raised when a User is not found.
"""
pass
class ChannelNotFound(ObjectNotFound):
"""
Exception raised when a Channel is not found.
"""
pass
class ThreadNotFound(ObjectNotFound):
"""
Exception raised when a Thread is not found.
"""
pass
class ChannelNotReadable(ObjectNotFound):
"""
Exception raised when a channel cannot be read.
"""
pass
class RoleNotFound(ObjectNotFound):
"""
Exception raised when a Role is not found.
"""
pass
class EmojiNotFound(ObjectNotFound):
"""
Exception raised when an Emoji is not found.
"""
pass
class GuildStickerNotFound(ObjectNotFound):
"""
Exception raised when a GuildSticker is not found.
"""
pass
class PartialEmojiConversionFailure(ObjectNotFound):
"""
Exception raised when a PartialEmoji conversion fails.
"""
pass
# Flag Argument Errors
class FlagError(BadArgument):
"""
Base exception for flag parsing errors.
"""
pass
class BadFlagArgument(FlagError):
"""
Exception raised when a flag argument is invalid.
"""
def __init__(self, flag: Flag) -> None: ...
@property
def flag(self) -> Flag: ...
class MissingFlagArgument(FlagError):
"""
Exception raised when a flag argument is missing.
"""
def __init__(self, flag: Flag) -> None: ...
@property
def flag(self) -> Flag: ...
class TooManyFlags(FlagError):
"""
Exception raised when too many flag arguments are provided.
"""
def __init__(self, flag: Flag, values: List[str]) -> None: ...
@property
def flag(self) -> Flag: ...
@property
def values(self) -> List[str]: ...
class MissingRequiredFlag(FlagError):
"""
Exception raised when a required flag is not provided.
"""
def __init__(self, flag: Flag) -> None: ...
@property
def flag(self) -> Flag: ...
# Command Registration Errors
class CommandRegistrationError(ClientException):
"""
Exception raised when command registration fails.
"""
passExceptions related to voice connections and audio processing.
class OpusError(DiscordException):
"""
Base exception for Opus codec errors.
"""
pass
class OpusNotLoaded(OpusError):
"""
Exception raised when Opus library is not available.
This occurs when trying to use voice features without the Opus codec installed.
"""
passExceptions for audio recording and sink operations.
class SinkException(DiscordException):
"""
Base exception for audio sink errors.
"""
pass
class RecordingException(SinkException):
"""
Exception raised during audio recording operations.
"""
pass
class MP3SinkError(SinkException):
"""
Exception raised for MP3 audio sink errors.
"""
pass
class MP4SinkError(SinkException):
"""
Exception raised for MP4 audio sink errors.
"""
pass
class OGGSinkError(SinkException):
"""
Exception raised for OGG audio sink errors.
"""
pass
class MKVSinkError(SinkException):
"""
Exception raised for MKV audio sink errors.
"""
pass
class WaveSinkError(SinkException):
"""
Exception raised for WAV audio sink errors.
"""
pass
class M4ASinkError(SinkException):
"""
Exception raised for M4A audio sink errors.
"""
pass
class MKASinkError(SinkException):
"""
Exception raised for MKA audio sink errors.
"""
pass
class OggError(DiscordException):
"""
Exception raised for OGG file parsing errors.
"""
passCommon patterns and best practices for handling errors in py-cord applications.
# Example: Basic Error Handling
@bot.event
async def on_application_command_error(ctx, error):
if isinstance(error, discord.Forbidden):
await ctx.respond("I don't have permission to do that!", ephemeral=True)
elif isinstance(error, discord.NotFound):
await ctx.respond("That resource wasn't found.", ephemeral=True)
elif isinstance(error, discord.HTTPException):
await ctx.respond(f"An HTTP error occurred: {error.text}", ephemeral=True)
else:
# Log unexpected errors
print(f"Unexpected error: {error}")
await ctx.respond("An unexpected error occurred.", ephemeral=True)
# Example: Command Extension Error Handling
@bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
return # Ignore command not found
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"Missing argument: {error.param.name}")
elif isinstance(error, commands.BadArgument):
await ctx.send("Invalid argument provided.")
elif isinstance(error, commands.CommandOnCooldown):
await ctx.send(f"Command is on cooldown. Try again in {error.retry_after:.1f}s")
elif isinstance(error, commands.MissingPermissions):
perms = ', '.join(error.missing_permissions)
await ctx.send(f"You're missing permissions: {perms}")
elif isinstance(error, commands.BotMissingPermissions):
perms = ', '.join(error.missing_permissions)
await ctx.send(f"I'm missing permissions: {perms}")
elif isinstance(error, commands.CheckFailure):
await ctx.send("You don't have permission to use this command.")
elif isinstance(error, commands.CommandInvokeError):
# Log the original error
print(f"Error in {ctx.command}: {error.original}")
await ctx.send("An error occurred while executing the command.")
# Example: Cog-specific Error Handling
class MyCog(commands.Cog):
async def cog_command_error(self, ctx, error):
if isinstance(error, commands.MissingRole):
await ctx.send(f"You need the {error.missing_role} role!")
else:
# Let the global error handler deal with it
raise error
# Example: Extension Loading Error Handling
try:
bot.load_extension('my_extension')
except commands.ExtensionNotFound:
print("Extension file not found")
except commands.ExtensionAlreadyLoaded:
print("Extension already loaded")
except commands.NoEntryPointError:
print("Extension missing setup function")
except commands.ExtensionFailed as e:
print(f"Extension failed to load: {e.original}")
# Example: HTTP Error Handling with Retry Logic
import asyncio
async def safe_api_call(coro, max_retries=3):
"""Safely execute an API call with retry logic."""
for attempt in range(max_retries):
try:
return await coro
except discord.HTTPException as e:
if e.status == 429: # Rate limited
# Discord sends retry-after header
retry_after = int(e.response.headers.get('Retry-After', 1))
await asyncio.sleep(retry_after)
continue
elif 500 <= e.status < 600: # Server error
if attempt < max_retries - 1:
await asyncio.sleep(2 ** attempt) # Exponential backoff
continue
raise # Re-raise if not retryable or max retries exceeded
raise discord.HTTPException(None, "Max retries exceeded")The error handling system provides comprehensive exception coverage for all aspects of Discord bot development, enabling robust error recovery, informative error messages, and proper debugging capabilities for production Discord applications.
Install with Tessl CLI
npx tessl i tessl/pypi-py-corddocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10