or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands-interactions.mdcore-clients.mddiscord-objects.mderror-handling.mdextensions.mdindex.mdui-components.mdutilities-helpers.md

error-handling.mddocs/

0

# Error Handling and Exceptions

1

2

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.

3

4

## Capabilities

5

6

### Core Discord Exceptions

7

8

Base exception classes for Discord-related errors and API failures.

9

10

```python { .api }

11

class DiscordException(Exception):

12

"""

13

Base exception class for Discord-related errors.

14

15

All discord.py exceptions inherit from this class.

16

"""

17

pass

18

19

class ClientException(DiscordException):

20

"""

21

Exception raised for client-side errors.

22

23

These are errors caused by incorrect usage of the library

24

rather than Discord API issues.

25

"""

26

pass

27

28

class NoMoreItems(DiscordException):

29

"""

30

Exception raised when an async iterator has no more items.

31

"""

32

pass

33

34

class GatewayNotFound(DiscordException):

35

"""

36

Exception raised when the Discord gateway endpoint is not found.

37

"""

38

pass

39

40

class ConnectionClosed(DiscordException):

41

"""

42

Exception raised when the gateway connection is closed unexpectedly.

43

"""

44

45

def __init__(self, original: Exception, shard_id: Optional[int] = None) -> None:

46

"""

47

Initialize connection closed exception.

48

49

Parameters:

50

- original: Exception - The original exception that caused the closure

51

- shard_id: int - ID of the shard that disconnected

52

"""

53

54

@property

55

def code(self) -> int:

56

"""The WebSocket close code."""

57

58

@property

59

def reason(self) -> str:

60

"""The reason for the connection closure."""

61

62

@property

63

def shard_id(self) -> Optional[int]:

64

"""The shard ID that disconnected."""

65

66

class PrivilegedIntentsRequired(ClientException):

67

"""

68

Exception raised when privileged intents are required but not enabled.

69

70

This occurs when trying to access features that require privileged intents

71

(message content, members, presences) without having them enabled.

72

"""

73

74

def __init__(self, shard_id: Optional[int] = None) -> None: ...

75

76

@property

77

def shard_id(self) -> Optional[int]: ...

78

79

class LoginFailure(DiscordException):

80

"""

81

Exception raised when bot login fails.

82

83

Usually caused by invalid bot token.

84

"""

85

pass

86

```

87

88

### HTTP and API Exceptions

89

90

Exceptions related to Discord's REST API and HTTP requests.

91

92

```python { .api }

93

class HTTPException(DiscordException):

94

"""

95

Base exception for HTTP-related errors with Discord's API.

96

"""

97

98

def __init__(

99

self,

100

response: aiohttp.ClientResponse,

101

message: Union[str, Dict[str, Any]]

102

) -> None: ...

103

104

@property

105

def response(self) -> aiohttp.ClientResponse:

106

"""The HTTP response that caused the exception."""

107

108

@property

109

def status(self) -> int:

110

"""HTTP status code."""

111

112

@property

113

def code(self) -> int:

114

"""Discord API error code."""

115

116

@property

117

def text(self) -> str:

118

"""Error message text."""

119

120

class Forbidden(HTTPException):

121

"""

122

Exception raised for 403 Forbidden HTTP responses.

123

124

Indicates insufficient permissions for the requested action.

125

"""

126

pass

127

128

class NotFound(HTTPException):

129

"""

130

Exception raised for 404 Not Found HTTP responses.

131

132

Indicates the requested resource doesn't exist.

133

"""

134

pass

135

136

class DiscordServerError(HTTPException):

137

"""

138

Exception raised for 5xx server error HTTP responses.

139

140

Indicates an error on Discord's side.

141

"""

142

pass

143

144

class InvalidData(DiscordException):

145

"""

146

Exception raised when Discord sends invalid or unexpected data.

147

"""

148

pass

149

150

class InvalidArgument(DiscordException):

151

"""

152

Exception raised when an invalid argument is passed to a function.

153

"""

154

pass

155

156

class ValidationError(DiscordException):

157

"""

158

Exception raised when data validation fails.

159

"""

160

pass

161

```

162

163

### Extension Management Exceptions

164

165

Exceptions related to loading and managing bot extensions and cogs.

166

167

```python { .api }

168

class ExtensionError(DiscordException):

169

"""

170

Base exception for extension-related errors.

171

"""

172

173

def __init__(self, message: str = None, *, name: str) -> None:

174

"""

175

Initialize extension error.

176

177

Parameters:

178

- message: str - Error message

179

- name: str - Extension name that caused the error

180

"""

181

182

@property

183

def name(self) -> str:

184

"""The name of the extension that caused the error."""

185

186

class ExtensionAlreadyLoaded(ExtensionError):

187

"""

188

Exception raised when trying to load an already loaded extension.

189

"""

190

pass

191

192

class ExtensionNotLoaded(ExtensionError):

193

"""

194

Exception raised when trying to reload/unload an extension that isn't loaded.

195

"""

196

pass

197

198

class NoEntryPointError(ExtensionError):

199

"""

200

Exception raised when an extension doesn't have a setup function.

201

202

Extensions must have either a 'setup' function or a 'Cog' class.

203

"""

204

pass

205

206

class ExtensionFailed(ExtensionError):

207

"""

208

Exception raised when an extension fails to load due to an error.

209

"""

210

211

def __init__(

212

self,

213

name: str,

214

original: Exception

215

) -> None:

216

"""

217

Initialize extension failed error.

218

219

Parameters:

220

- name: str - Extension name

221

- original: Exception - The original exception that caused the failure

222

"""

223

224

@property

225

def original(self) -> Exception:

226

"""The original exception that caused the extension to fail."""

227

228

class ExtensionNotFound(ExtensionError):

229

"""

230

Exception raised when an extension file cannot be found.

231

"""

232

pass

233

```

234

235

### Application Command Exceptions

236

237

Exceptions specific to application commands (slash commands, context menus).

238

239

```python { .api }

240

class ApplicationCommandError(DiscordException):

241

"""

242

Base exception for application command errors.

243

"""

244

pass

245

246

class ApplicationCommandInvokeError(ApplicationCommandError):

247

"""

248

Exception raised when an application command raises an unhandled error.

249

"""

250

251

def __init__(self, command: ApplicationCommand, original: Exception) -> None:

252

"""

253

Initialize command invoke error.

254

255

Parameters:

256

- command: ApplicationCommand - The command that failed

257

- original: Exception - The original exception

258

"""

259

260

@property

261

def command(self) -> ApplicationCommand:

262

"""The command that caused the error."""

263

264

@property

265

def original(self) -> Exception:

266

"""The original exception that was raised."""

267

268

class CheckFailure(ApplicationCommandError):

269

"""

270

Exception raised when an application command check fails.

271

"""

272

pass

273

274

class InteractionResponded(ApplicationCommandError):

275

"""

276

Exception raised when trying to respond to an already responded interaction.

277

"""

278

279

def __init__(self, interaction: Interaction) -> None: ...

280

281

@property

282

def interaction(self) -> Interaction: ...

283

```

284

285

### Command Framework Exceptions (discord.ext.commands)

286

287

Extensive exception system for the commands extension framework.

288

289

```python { .api }

290

# Base Command Errors

291

class CommandError(DiscordException):

292

"""

293

Base exception for command-related errors in the commands extension.

294

"""

295

296

def __init__(self, message: str = None, *args) -> None: ...

297

298

class UserInputError(CommandError):

299

"""

300

Base exception for errors caused by user input.

301

"""

302

pass

303

304

class CommandNotFound(CommandError):

305

"""

306

Exception raised when a command is not found.

307

"""

308

pass

309

310

class MissingRequiredArgument(UserInputError):

311

"""

312

Exception raised when a required command argument is missing.

313

"""

314

315

def __init__(self, param: inspect.Parameter) -> None:

316

"""

317

Initialize missing argument error.

318

319

Parameters:

320

- param: Parameter - The missing parameter

321

"""

322

323

@property

324

def param(self) -> inspect.Parameter:

325

"""The missing parameter."""

326

327

class TooManyArguments(UserInputError):

328

"""

329

Exception raised when too many arguments are provided to a command.

330

"""

331

pass

332

333

class BadArgument(UserInputError):

334

"""

335

Exception raised when argument conversion fails.

336

"""

337

pass

338

339

class ArgumentParsingError(UserInputError):

340

"""

341

Exception raised when argument parsing fails.

342

"""

343

pass

344

345

class UnexpectedQuoteError(ArgumentParsingError):

346

"""

347

Exception raised when an unexpected quote character is found.

348

"""

349

350

def __init__(self, quote: str) -> None: ...

351

352

@property

353

def quote(self) -> str: ...

354

355

class InvalidEndOfQuotedStringError(ArgumentParsingError):

356

"""

357

Exception raised when a quoted string doesn't end properly.

358

"""

359

360

def __init__(self, char: str) -> None: ...

361

362

@property

363

def char(self) -> str: ...

364

365

class ExpectedClosingQuoteError(ArgumentParsingError):

366

"""

367

Exception raised when a closing quote is expected but not found.

368

"""

369

370

def __init__(self, close_quote: str) -> None: ...

371

372

@property

373

def close_quote(self) -> str: ...

374

375

# Check Failures

376

class CheckFailure(CommandError):

377

"""

378

Exception raised when a command check fails.

379

"""

380

pass

381

382

class CheckAnyFailure(CheckFailure):

383

"""

384

Exception raised when all checks in a check_any decorator fail.

385

"""

386

387

def __init__(self, checks: List[Callable], errors: List[CheckFailure]) -> None: ...

388

389

@property

390

def checks(self) -> List[Callable]: ...

391

@property

392

def errors(self) -> List[CheckFailure]: ...

393

394

class PrivateMessageOnly(CheckFailure):

395

"""

396

Exception raised when a command can only be used in private messages.

397

"""

398

pass

399

400

class NoPrivateMessage(CheckFailure):

401

"""

402

Exception raised when a command cannot be used in private messages.

403

"""

404

pass

405

406

class NotOwner(CheckFailure):

407

"""

408

Exception raised when a command requires the user to be the bot owner.

409

"""

410

pass

411

412

class MissingRole(CheckFailure):

413

"""

414

Exception raised when a user is missing a required role.

415

"""

416

417

def __init__(self, missing_role: Union[str, int]) -> None: ...

418

419

@property

420

def missing_role(self) -> Union[str, int]: ...

421

422

class BotMissingRole(CheckFailure):

423

"""

424

Exception raised when the bot is missing a required role.

425

"""

426

427

def __init__(self, missing_role: Union[str, int]) -> None: ...

428

429

@property

430

def missing_role(self) -> Union[str, int]: ...

431

432

class MissingAnyRole(CheckFailure):

433

"""

434

Exception raised when a user is missing all required roles.

435

"""

436

437

def __init__(self, missing_roles: List[Union[str, int]]) -> None: ...

438

439

@property

440

def missing_roles(self) -> List[Union[str, int]]: ...

441

442

class BotMissingAnyRole(CheckFailure):

443

"""

444

Exception raised when the bot is missing all required roles.

445

"""

446

447

def __init__(self, missing_roles: List[Union[str, int]]) -> None: ...

448

449

@property

450

def missing_roles(self) -> List[Union[str, int]]: ...

451

452

class MissingPermissions(CheckFailure):

453

"""

454

Exception raised when a user is missing required permissions.

455

"""

456

457

def __init__(self, missing_permissions: List[str], *args) -> None: ...

458

459

@property

460

def missing_permissions(self) -> List[str]: ...

461

462

class BotMissingPermissions(CheckFailure):

463

"""

464

Exception raised when the bot is missing required permissions.

465

"""

466

467

def __init__(self, missing_permissions: List[str], *args) -> None: ...

468

469

@property

470

def missing_permissions(self) -> List[str]: ...

471

472

class NSFWChannelRequired(CheckFailure):

473

"""

474

Exception raised when a command requires an NSFW channel.

475

"""

476

477

def __init__(self, channel: GuildChannel) -> None: ...

478

479

@property

480

def channel(self) -> GuildChannel: ...

481

482

# Command Execution Errors

483

class DisabledCommand(CommandError):

484

"""

485

Exception raised when a disabled command is invoked.

486

"""

487

pass

488

489

class CommandInvokeError(CommandError):

490

"""

491

Exception raised when a command raises an unhandled exception.

492

"""

493

494

def __init__(self, command: Command, original: Exception) -> None: ...

495

496

@property

497

def command(self) -> Command: ...

498

@property

499

def original(self) -> Exception: ...

500

501

class CommandOnCooldown(CommandError):

502

"""

503

Exception raised when a command is on cooldown.

504

"""

505

506

def __init__(

507

self,

508

cooldown: Cooldown,

509

retry_after: float,

510

type: BucketType

511

) -> None: ...

512

513

@property

514

def cooldown(self) -> Cooldown: ...

515

@property

516

def retry_after(self) -> float: ...

517

@property

518

def type(self) -> BucketType: ...

519

520

class MaxConcurrencyReached(CommandError):

521

"""

522

Exception raised when a command's max concurrency is reached.

523

"""

524

525

def __init__(self, number: int, per: BucketType) -> None: ...

526

527

@property

528

def number(self) -> int: ...

529

@property

530

def per(self) -> BucketType: ...

531

532

# Conversion Errors

533

class ConversionError(CommandError):

534

"""

535

Base exception for argument conversion errors.

536

"""

537

538

def __init__(self, converter: Any, original: Exception) -> None: ...

539

540

@property

541

def converter(self) -> Any: ...

542

@property

543

def original(self) -> Exception: ...

544

545

class BadUnionArgument(UserInputError):

546

"""

547

Exception raised when a Union converter fails.

548

"""

549

550

def __init__(

551

self,

552

param: inspect.Parameter,

553

converters: Tuple[Type, ...],

554

errors: List[CommandError]

555

) -> None: ...

556

557

@property

558

def param(self) -> inspect.Parameter: ...

559

@property

560

def converters(self) -> Tuple[Type, ...]: ...

561

@property

562

def errors(self) -> List[CommandError]: ...

563

564

class BadLiteralArgument(UserInputError):

565

"""

566

Exception raised when a Literal converter fails.

567

"""

568

569

def __init__(

570

self,

571

param: inspect.Parameter,

572

literals: Tuple[Any, ...],

573

argument: str

574

) -> None: ...

575

576

@property

577

def param(self) -> inspect.Parameter: ...

578

@property

579

def literals(self) -> Tuple[Any, ...]: ...

580

@property

581

def argument(self) -> str: ...

582

583

class BadBoolArgument(BadArgument):

584

"""

585

Exception raised when a boolean conversion fails.

586

"""

587

588

def __init__(self, argument: str) -> None: ...

589

590

@property

591

def argument(self) -> str: ...

592

593

class BadColourArgument(BadArgument):

594

"""

595

Exception raised when a Colour conversion fails.

596

"""

597

598

def __init__(self, argument: str) -> None: ...

599

600

@property

601

def argument(self) -> str: ...

602

603

class BadColorArgument(BadColourArgument):

604

"""

605

Alias for BadColourArgument using American spelling.

606

"""

607

pass

608

609

class BadInviteArgument(BadArgument):

610

"""

611

Exception raised when an Invite conversion fails.

612

"""

613

pass

614

615

# Object Not Found Errors

616

class ObjectNotFound(BadArgument):

617

"""

618

Base exception for when a Discord object is not found.

619

"""

620

621

def __init__(self, argument: str) -> None: ...

622

623

@property

624

def argument(self) -> str: ...

625

626

class MessageNotFound(ObjectNotFound):

627

"""

628

Exception raised when a Message is not found.

629

"""

630

pass

631

632

class MemberNotFound(ObjectNotFound):

633

"""

634

Exception raised when a Member is not found.

635

"""

636

pass

637

638

class GuildNotFound(ObjectNotFound):

639

"""

640

Exception raised when a Guild is not found.

641

"""

642

pass

643

644

class UserNotFound(ObjectNotFound):

645

"""

646

Exception raised when a User is not found.

647

"""

648

pass

649

650

class ChannelNotFound(ObjectNotFound):

651

"""

652

Exception raised when a Channel is not found.

653

"""

654

pass

655

656

class ThreadNotFound(ObjectNotFound):

657

"""

658

Exception raised when a Thread is not found.

659

"""

660

pass

661

662

class ChannelNotReadable(ObjectNotFound):

663

"""

664

Exception raised when a channel cannot be read.

665

"""

666

pass

667

668

class RoleNotFound(ObjectNotFound):

669

"""

670

Exception raised when a Role is not found.

671

"""

672

pass

673

674

class EmojiNotFound(ObjectNotFound):

675

"""

676

Exception raised when an Emoji is not found.

677

"""

678

pass

679

680

class GuildStickerNotFound(ObjectNotFound):

681

"""

682

Exception raised when a GuildSticker is not found.

683

"""

684

pass

685

686

class PartialEmojiConversionFailure(ObjectNotFound):

687

"""

688

Exception raised when a PartialEmoji conversion fails.

689

"""

690

pass

691

692

# Flag Argument Errors

693

class FlagError(BadArgument):

694

"""

695

Base exception for flag parsing errors.

696

"""

697

pass

698

699

class BadFlagArgument(FlagError):

700

"""

701

Exception raised when a flag argument is invalid.

702

"""

703

704

def __init__(self, flag: Flag) -> None: ...

705

706

@property

707

def flag(self) -> Flag: ...

708

709

class MissingFlagArgument(FlagError):

710

"""

711

Exception raised when a flag argument is missing.

712

"""

713

714

def __init__(self, flag: Flag) -> None: ...

715

716

@property

717

def flag(self) -> Flag: ...

718

719

class TooManyFlags(FlagError):

720

"""

721

Exception raised when too many flag arguments are provided.

722

"""

723

724

def __init__(self, flag: Flag, values: List[str]) -> None: ...

725

726

@property

727

def flag(self) -> Flag: ...

728

@property

729

def values(self) -> List[str]: ...

730

731

class MissingRequiredFlag(FlagError):

732

"""

733

Exception raised when a required flag is not provided.

734

"""

735

736

def __init__(self, flag: Flag) -> None: ...

737

738

@property

739

def flag(self) -> Flag: ...

740

741

# Command Registration Errors

742

class CommandRegistrationError(ClientException):

743

"""

744

Exception raised when command registration fails.

745

"""

746

pass

747

```

748

749

### Audio and Voice Exceptions

750

751

Exceptions related to voice connections and audio processing.

752

753

```python { .api }

754

class OpusError(DiscordException):

755

"""

756

Base exception for Opus codec errors.

757

"""

758

pass

759

760

class OpusNotLoaded(OpusError):

761

"""

762

Exception raised when Opus library is not available.

763

764

This occurs when trying to use voice features without the Opus codec installed.

765

"""

766

pass

767

```

768

769

### Audio Sink Exceptions

770

771

Exceptions for audio recording and sink operations.

772

773

```python { .api }

774

class SinkException(DiscordException):

775

"""

776

Base exception for audio sink errors.

777

"""

778

pass

779

780

class RecordingException(SinkException):

781

"""

782

Exception raised during audio recording operations.

783

"""

784

pass

785

786

class MP3SinkError(SinkException):

787

"""

788

Exception raised for MP3 audio sink errors.

789

"""

790

pass

791

792

class MP4SinkError(SinkException):

793

"""

794

Exception raised for MP4 audio sink errors.

795

"""

796

pass

797

798

class OGGSinkError(SinkException):

799

"""

800

Exception raised for OGG audio sink errors.

801

"""

802

pass

803

804

class MKVSinkError(SinkException):

805

"""

806

Exception raised for MKV audio sink errors.

807

"""

808

pass

809

810

class WaveSinkError(SinkException):

811

"""

812

Exception raised for WAV audio sink errors.

813

"""

814

pass

815

816

class M4ASinkError(SinkException):

817

"""

818

Exception raised for M4A audio sink errors.

819

"""

820

pass

821

822

class MKASinkError(SinkException):

823

"""

824

Exception raised for MKA audio sink errors.

825

"""

826

pass

827

828

class OggError(DiscordException):

829

"""

830

Exception raised for OGG file parsing errors.

831

"""

832

pass

833

```

834

835

### Error Handling Patterns

836

837

Common patterns and best practices for handling errors in py-cord applications.

838

839

```python

840

# Example: Basic Error Handling

841

@bot.event

842

async def on_application_command_error(ctx, error):

843

if isinstance(error, discord.Forbidden):

844

await ctx.respond("I don't have permission to do that!", ephemeral=True)

845

elif isinstance(error, discord.NotFound):

846

await ctx.respond("That resource wasn't found.", ephemeral=True)

847

elif isinstance(error, discord.HTTPException):

848

await ctx.respond(f"An HTTP error occurred: {error.text}", ephemeral=True)

849

else:

850

# Log unexpected errors

851

print(f"Unexpected error: {error}")

852

await ctx.respond("An unexpected error occurred.", ephemeral=True)

853

854

# Example: Command Extension Error Handling

855

@bot.event

856

async def on_command_error(ctx, error):

857

if isinstance(error, commands.CommandNotFound):

858

return # Ignore command not found

859

elif isinstance(error, commands.MissingRequiredArgument):

860

await ctx.send(f"Missing argument: {error.param.name}")

861

elif isinstance(error, commands.BadArgument):

862

await ctx.send("Invalid argument provided.")

863

elif isinstance(error, commands.CommandOnCooldown):

864

await ctx.send(f"Command is on cooldown. Try again in {error.retry_after:.1f}s")

865

elif isinstance(error, commands.MissingPermissions):

866

perms = ', '.join(error.missing_permissions)

867

await ctx.send(f"You're missing permissions: {perms}")

868

elif isinstance(error, commands.BotMissingPermissions):

869

perms = ', '.join(error.missing_permissions)

870

await ctx.send(f"I'm missing permissions: {perms}")

871

elif isinstance(error, commands.CheckFailure):

872

await ctx.send("You don't have permission to use this command.")

873

elif isinstance(error, commands.CommandInvokeError):

874

# Log the original error

875

print(f"Error in {ctx.command}: {error.original}")

876

await ctx.send("An error occurred while executing the command.")

877

878

# Example: Cog-specific Error Handling

879

class MyCog(commands.Cog):

880

async def cog_command_error(self, ctx, error):

881

if isinstance(error, commands.MissingRole):

882

await ctx.send(f"You need the {error.missing_role} role!")

883

else:

884

# Let the global error handler deal with it

885

raise error

886

887

# Example: Extension Loading Error Handling

888

try:

889

bot.load_extension('my_extension')

890

except commands.ExtensionNotFound:

891

print("Extension file not found")

892

except commands.ExtensionAlreadyLoaded:

893

print("Extension already loaded")

894

except commands.NoEntryPointError:

895

print("Extension missing setup function")

896

except commands.ExtensionFailed as e:

897

print(f"Extension failed to load: {e.original}")

898

899

# Example: HTTP Error Handling with Retry Logic

900

import asyncio

901

902

async def safe_api_call(coro, max_retries=3):

903

"""Safely execute an API call with retry logic."""

904

for attempt in range(max_retries):

905

try:

906

return await coro

907

except discord.HTTPException as e:

908

if e.status == 429: # Rate limited

909

# Discord sends retry-after header

910

retry_after = int(e.response.headers.get('Retry-After', 1))

911

await asyncio.sleep(retry_after)

912

continue

913

elif 500 <= e.status < 600: # Server error

914

if attempt < max_retries - 1:

915

await asyncio.sleep(2 ** attempt) # Exponential backoff

916

continue

917

raise # Re-raise if not retryable or max retries exceeded

918

919

raise discord.HTTPException(None, "Max retries exceeded")

920

```

921

922

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.