-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
feat: add Bun templates for create-discord-bot #11348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add Bun templates for create-discord-bot #11348
Conversation
- Add TypeScript Bun template with complete src structure - Add JavaScript Bun template with complete src structure - Both templates mirror the Node.js versions with Bun-specific configuration Closes discordjs#11346
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
📝 WalkthroughWalkthroughThis PR implements Bun bot templates for Changes
Sequence Diagram(s)sequenceDiagram
participant Main as Bot Entry Point
participant Discord as Discord Client
participant EventMgr as Event Manager
participant CmdLoader as Command Loader
participant Interaction
participant CmdRouter as InteractionCreate Handler
participant Command as Command Handler
Main->>Main: Load Events (top-level await)
Main->>EventMgr: Register all loaded events<br/>(once/on based on flag)
Main->>Discord: Client.login(DISCORD_TOKEN)
Note over Main: Bot initialization complete
Interaction->>Discord: Dispatch InteractionCreate
Discord->>CmdRouter: Execute InteractionCreate handler
CmdRouter->>CmdRouter: Load Commands (cached)
CmdRouter->>CmdRouter: Check if interaction.isCommand()
alt Is Command
CmdRouter->>CmdRouter: Lookup command by name
alt Command Found
CmdRouter->>Command: command.execute(interaction)
Command->>Interaction: interaction.reply()
else Command Not Found
CmdRouter->>CmdRouter: throw error
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (23)
packages/create-discord-bot/template/Bun/JavaScript/.prettierignore(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/.prettierrc.json(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/commands/index.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/commands/ping.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/commands/utility/user.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/events/index.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/events/interactionCreate.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/events/ready.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/index.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/util/deploy.js(1 hunks)packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/.gitignore(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/.prettierignore(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/.prettierrc.json(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/commands/ping.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/commands/utility/user.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/events/interactionCreate.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/events/ready.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/index.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/util/deploy.ts(1 hunks)packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (11)
packages/create-discord-bot/template/Bun/TypeScript/src/events/ready.ts (2)
packages/create-discord-bot/template/Bun/JavaScript/src/index.js (1)
client(7-7)packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts (1)
Event(8-25)
packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (3)
packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (3)
loadStructures(21-58)loadCommands(60-65)loadEvents(67-69)packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts (1)
predicate(32-33)packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts (1)
predicate(39-40)
packages/create-discord-bot/template/Bun/JavaScript/src/events/interactionCreate.js (2)
packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (1)
loadCommands(64-69)packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (1)
loadCommands(60-65)
packages/create-discord-bot/template/Bun/JavaScript/src/events/ready.js (1)
packages/create-discord-bot/template/Bun/JavaScript/src/index.js (1)
client(7-7)
packages/create-discord-bot/template/Bun/TypeScript/src/commands/ping.ts (1)
packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts (1)
Command(8-19)
packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts (2)
packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts (2)
schema(30-34)predicate(39-40)packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (1)
StructurePredicate(11-11)
packages/create-discord-bot/template/Bun/TypeScript/src/index.ts (3)
packages/create-discord-bot/template/Bun/JavaScript/src/index.js (2)
client(7-7)events(10-10)packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (1)
loadEvents(76-78)packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (1)
loadEvents(67-69)
packages/create-discord-bot/template/Bun/TypeScript/src/util/deploy.ts (3)
packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (1)
loadCommands(60-65)packages/rest/src/lib/REST.ts (1)
REST(37-478)packages/core/src/api/index.ts (1)
API(40-97)
packages/create-discord-bot/template/Bun/TypeScript/src/commands/utility/user.ts (1)
packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts (1)
Command(8-19)
packages/create-discord-bot/template/Bun/TypeScript/src/events/interactionCreate.ts (3)
packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (1)
loadCommands(64-69)packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (1)
loadCommands(60-65)packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts (1)
Event(8-25)
packages/create-discord-bot/template/Bun/JavaScript/src/index.js (1)
packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (1)
loadEvents(76-78)
🔇 Additional comments (26)
packages/create-discord-bot/template/Bun/TypeScript/.gitignore (1)
1-5: Verify .gitignore completeness against Node.js template and Bun-specific patterns.The
.gitignorecovers common Node.js artifacts (node_modules/, dist/, .env, .DS_Store, *.log), but needs verification:
- Does the existing Node.js template
.gitignoreinclude additional patterns (IDE-specific files, .env variants)?- Should Bun-specific patterns be added (e.g.,
.bunor.cachedirectories if Bun's build tools generate them)?Since the PR objective states templates should be "similar to the existing Node.js templates," ensure this matches the Node.js TypeScript template's
.gitignore.packages/create-discord-bot/template/Bun/JavaScript/.prettierignore (1)
1-1: LGTM!Standard practice to exclude lock files from Prettier formatting.
packages/create-discord-bot/template/Bun/JavaScript/.prettierrc.json (1)
1-9: LGTM!Well-structured Prettier configuration with appropriate settings for the template.
packages/create-discord-bot/template/Bun/TypeScript/.prettierrc.json (1)
1-9: LGTM!Configuration is consistent with the JavaScript template, ensuring uniform formatting across both Bun templates.
packages/create-discord-bot/template/Bun/TypeScript/src/commands/utility/user.ts (1)
1-11: Command structure is correct.The implementation correctly conforms to the
Commandinterface and follows the established pattern in the template.packages/create-discord-bot/template/Bun/TypeScript/src/util/deploy.ts (1)
1-8: Command loading and registration logic looks good.The script correctly loads commands, extracts their data, and prepares them for bulk registration.
packages/create-discord-bot/template/Bun/JavaScript/src/index.js (1)
12-24: Event registration and bot initialization look good.The implementation correctly:
- Distinguishes between
onceandonevent handlers- Wraps event execution in try/catch to prevent unhandled promise rejections
- Uses
voidto explicitly handle the unawaited login Promisepackages/create-discord-bot/template/Bun/TypeScript/src/index.ts (2)
1-4: LGTM! Import structure is correct.The imports are properly structured for Bun's TypeScript runtime, including the
.tsextension in the loadEvents import which Bun supports.
13-21: LGTM! Event handler registration with proper error handling.The event registration logic correctly handles both
onceandonevents, and includes try/catch for individual event execution failures.packages/create-discord-bot/template/Bun/JavaScript/src/commands/utility/user.js (1)
1-10: LGTM! Simple and correct command implementation.The command structure is correct with proper JSDoc type annotation, and the execute function appropriately replies with the user's username.
packages/create-discord-bot/template/Bun/TypeScript/src/events/ready.ts (1)
1-10: LGTM! Proper TypeScript event handler with satisfies.The event handler correctly implements the
Event<Events.ClientReady>contract using thesatisfiesoperator for type safety while preserving literal types.packages/create-discord-bot/template/Bun/JavaScript/src/commands/ping.js (1)
1-10: LGTM! Simple and correct ping command.The command structure is correct with proper JSDoc type annotation, and appropriately replies with "Pong!".
packages/create-discord-bot/template/Bun/JavaScript/src/commands/index.js (1)
1-25: LGTM! Clean validation infrastructure.The Command validation system using Zod provides runtime type safety and integrates well with the loader utilities.
packages/create-discord-bot/template/Bun/JavaScript/src/events/ready.js (1)
1-10: LGTM! Correct event handler implementation.The event handler correctly implements the ClientReady event with proper JSDoc type annotation and appropriate logging.
packages/create-discord-bot/template/Bun/TypeScript/src/commands/ping.ts (1)
1-11: LGTM! Type-safe command implementation.The command correctly uses the
satisfies Commandoperator to ensure type safety while preserving literal types for the data object.packages/create-discord-bot/template/Bun/TypeScript/src/events/interactionCreate.ts (1)
1-6: LGTM on imports and command loading.The top-level await pattern for loading commands at module initialization is appropriate for Bun/ES modules and ensures commands are ready before any interaction is processed.
packages/create-discord-bot/template/Bun/JavaScript/src/events/index.js (1)
1-29: Well-structured event schema and validation.The zod schema correctly validates the Event structure, and using
safeParsefor the predicate is the right approach for non-throwing validation. The JSDoc typedef provides good type hints for JavaScript users.packages/create-discord-bot/template/Bun/TypeScript/src/events/index.ts (1)
1-40: Clean type definitions with good documentation.The generic
Eventtype with proper constraints, comprehensive JSDoc, and the runtime validation schema provide both compile-time and runtime safety. The implementation is consistent with the JavaScript counterpart.packages/create-discord-bot/template/Bun/TypeScript/src/commands/index.ts (1)
1-33: LGTM!The Command type is well-defined with proper discord.js types. The zod schema provides adequate runtime shape validation, and the pattern is consistent with the events module.
packages/create-discord-bot/template/Bun/JavaScript/src/events/interactionCreate.js (1)
7-8: Good use of JSDoc for type annotation.The JSDoc type annotation correctly references the Event type from the index module, providing type safety in JavaScript.
packages/create-discord-bot/template/Bun/JavaScript/src/util/loaders.js (3)
23-57: LGTM!The
loadStructuresfunction correctly:
- Validates that the provided path is a directory
- Handles both URL and string paths
- Uses glob patterns to find
.jsfiles recursively (when enabled)- Skips
index.jsto avoid circular imports- Dynamically imports and validates structures using the predicate
64-78: LGTM!The
loadCommandsandloadEventsfunctions correctly wraploadStructureswith appropriate predicates. Thereducepattern for building the command Map by name is idiomatic and matches the TypeScript template implementation.
1-5: No action needed. Bun fully implements and supports thenode:fs/promises.globAPI, including all standard options (pattern strings/arrays,exclude,withFileTypes). Usingfs/promises.globis appropriate for a Bun template as it maintains compatibility with Node.js while working seamlessly in Bun's runtime.packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts (3)
1-6: Verify Bun compatibility withnode:fs/promisesglob API.Same concern as the JavaScript variant: the
globfunction fromnode:fs/promisesis a Node.js 22+ API. Consider using Bun's native glob functionality (Bun.glob()) for better compatibility and performance in this Bun-specific template.The
.tsimport extensions on lines 5-6 are correct for Bun's native TypeScript support.
21-58: LGTM!The generic
loadStructuresfunction is well-typed and correctly implements:
- Directory validation with clear error messaging
- URL/string path handling
- Recursive glob pattern construction for
.tsfiles- Index file exclusion to prevent circular imports
- Dynamic import with predicate validation
The implementation aligns with the established pattern from the relevant code snippets.
60-69: LGTM!Both
loadCommandsandloadEventsare properly typed and follow the same pattern as the reference TypeScript implementation. The Map reduction for commands correctly keys bycur.data.name.
packages/create-discord-bot/template/Bun/JavaScript/src/commands/index.js
Show resolved
Hide resolved
| async execute(interaction) { | ||
| if (interaction.isCommand()) { | ||
| const command = commands.get(interaction.commandName); | ||
|
|
||
| if (!command) { | ||
| throw new Error(`Command '${interaction.commandName}' not found.`); | ||
| } | ||
|
|
||
| await command.execute(interaction); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue: throwing leaves the interaction unacknowledged.
This has the same problem as the TypeScript version. The thrown error will cause the interaction to timeout without user feedback.
async execute(interaction) {
if (interaction.isCommand()) {
const command = commands.get(interaction.commandName);
if (!command) {
- throw new Error(`Command '${interaction.commandName}' not found.`);
+ console.error(`Command '${interaction.commandName}' not found.`);
+ await interaction.reply({ content: 'Unknown command.', ephemeral: true });
+ return;
}
await command.execute(interaction);
}
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async execute(interaction) { | |
| if (interaction.isCommand()) { | |
| const command = commands.get(interaction.commandName); | |
| if (!command) { | |
| throw new Error(`Command '${interaction.commandName}' not found.`); | |
| } | |
| await command.execute(interaction); | |
| } | |
| async execute(interaction) { | |
| if (interaction.isCommand()) { | |
| const command = commands.get(interaction.commandName); | |
| if (!command) { | |
| console.error(`Command '${interaction.commandName}' not found.`); | |
| await interaction.reply({ content: 'Unknown command.', ephemeral: true }); | |
| return; | |
| } | |
| await command.execute(interaction); | |
| } | |
| }, |
🤖 Prompt for AI Agents
In
packages/create-discord-bot/template/Bun/JavaScript/src/events/interactionCreate.js
around lines 10 to 19, do not throw when a command is missing or when
command.execute fails because that leaves the interaction unacknowledged;
instead, if commands.get(...) returns falsy, send an ephemeral reply to the
interaction indicating the command was not found and return; wrap
command.execute(interaction) in a try/catch and in the catch send an error
response: if interaction.deferred or interaction.replied use
interaction.followUp({ content: 'An error occurred while executing that
command.', ephemeral: true }) else use interaction.reply({ content: 'An error
occurred while executing that command.', ephemeral: true }); ensure you return
after responding so the event handler completes.
| // Load the events and commands | ||
| const events = await loadEvents(new URL('events/', import.meta.url)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is slightly misleading.
The comment says "Load the events and commands" but only events are loaded here. Commands are loaded within the interactionCreate event handler.
-// Load the events and commands
+// Load the events
const events = await loadEvents(new URL('events/', import.meta.url));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Load the events and commands | |
| const events = await loadEvents(new URL('events/', import.meta.url)); | |
| // Load the events | |
| const events = await loadEvents(new URL('events/', import.meta.url)); |
🤖 Prompt for AI Agents
In packages/create-discord-bot/template/Bun/JavaScript/src/index.js around lines
9-10, the inline comment "Load the events and commands" is misleading because
only events are loaded at this call; commands are loaded later inside the
interactionCreate handler. Update the comment to accurately reflect behavior
(e.g., "Load the events" or "Load the events (commands are loaded in
interactionCreate)") so it matches the code flow.
| const commands = await loadCommands(new URL('../commands/', import.meta.url)); | ||
| const commandData = [...commands.values()].map((command) => command.data); | ||
|
|
||
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for required environment variables.
The DISCORD_TOKEN environment variable is accessed without validation. If undefined, the REST client will fail with an unclear error message.
Apply this diff to add validation:
+if (!process.env.DISCORD_TOKEN || !process.env.APPLICATION_ID) {
+ throw new Error('Missing required environment variables: DISCORD_TOKEN and APPLICATION_ID must be set.');
+}
+
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); | |
| if (!process.env.DISCORD_TOKEN || !process.env.APPLICATION_ID) { | |
| throw new Error('Missing required environment variables: DISCORD_TOKEN and APPLICATION_ID must be set.'); | |
| } | |
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); |
🤖 Prompt for AI Agents
In packages/create-discord-bot/template/Bun/JavaScript/src/util/deploy.js around
line 10, the code uses process.env.DISCORD_TOKEN directly when creating the REST
client; add a validation step before this line that checks for a non-empty
DISCORD_TOKEN and fails fast with a clear error (throw or console.error +
process.exit(1)) if it's missing; update the code to read the token into a local
const after validation and use that const when calling new
REST(...).setToken(...), optionally doing the same pattern for any other
required env vars.
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); | ||
| const api = new API(rest); | ||
|
|
||
| const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID, commandData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for the API call.
The bulkOverwriteGlobalCommands call has no error handling. If registration fails (e.g., invalid token, network error, malformed command data), the script will crash with a potentially unclear error message.
Apply this diff to add error handling:
-const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID, commandData);
-
-console.log(`Successfully registered ${result.length} commands.`);
+try {
+ const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID, commandData);
+ console.log(`Successfully registered ${result.length} commands.`);
+} catch (error) {
+ console.error('Failed to register commands:', error);
+ process.exit(1);
+}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/create-discord-bot/template/Bun/JavaScript/src/util/deploy.js around
line 13, the call to api.applicationCommands.bulkOverwriteGlobalCommands lacks
error handling; wrap this async call in a try/catch, log a clear error message
including the caught error and relevant context (e.g., APPLICATION_ID and number
of commands), and exit or rethrow with a non-zero status so failures are
surfaced clearly; also validate that process.env.APPLICATION_ID exists before
calling and handle that case with a logged error and early exit.
| description: 'Provides information about the user.', | ||
| }, | ||
| async execute(interaction) { | ||
| await interaction.reply(`This command was run bu ${interaction.user.username}.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo in reply message.
"bu" should be "by".
- await interaction.reply(`This command was run bu ${interaction.user.username}.`);
+ await interaction.reply(`This command was run by ${interaction.user.username}.`);🤖 Prompt for AI Agents
In
packages/create-discord-bot/template/Bun/TypeScript/src/commands/utility/user.ts
around line 9, the reply message contains a typo: "This command was run bu ..."
— change "bu" to "by" so the string reads "This command was run by
${interaction.user.username}." and ensure punctuation remains correct.
| async execute(interaction) { | ||
| if (interaction.isCommand()) { | ||
| const command = commands.get(interaction.commandName); | ||
|
|
||
| if (!command) { | ||
| throw new Error(`Command '${interaction.commandName}' not found.`); | ||
| } | ||
|
|
||
| await command.execute(interaction); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing an unhandled error will crash the bot or timeout the interaction.
When a command isn't found, throwing an error leaves the interaction unacknowledged, causing Discord to show "The application did not respond" to the user. Additionally, unhandled exceptions in event handlers can destabilize the bot.
Consider replying with an ephemeral error message instead:
async execute(interaction) {
if (interaction.isCommand()) {
const command = commands.get(interaction.commandName);
if (!command) {
- throw new Error(`Command '${interaction.commandName}' not found.`);
+ console.error(`Command '${interaction.commandName}' not found.`);
+ await interaction.reply({ content: 'Unknown command.', ephemeral: true });
+ return;
}
await command.execute(interaction);
}
},🤖 Prompt for AI Agents
In
packages/create-discord-bot/template/Bun/TypeScript/src/events/interactionCreate.ts
around lines 10–19, do not throw when a command is missing: instead detect
missing command and reply to the interaction with an ephemeral error message (or
if the interaction was already deferred, use followUp) so the user sees a
response; wrap command execution in a try/catch, log the error, and send an
ephemeral generic error reply on exceptions (checking
interaction.replied/interaction.deferred and using interaction.reply or
interaction.followUp accordingly) to avoid leaving the interaction
unacknowledged and prevent unhandled exceptions from crashing the bot.
| } | ||
|
|
||
| // Login to the client | ||
| void client.login(process.env.DISCORD_TOKEN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation and error handling for client login.
Two issues:
DISCORD_TOKENis accessed without validation - if undefined, login will fail with an unclear error- Using
voiddiscards the login promise, preventing error handling for login failures
Apply this diff to add validation and proper error handling:
-// Login to the client
-void client.login(process.env.DISCORD_TOKEN);
+// Validate environment variable
+if (!process.env.DISCORD_TOKEN) {
+ throw new Error('Missing required environment variable: DISCORD_TOKEN must be set.');
+}
+
+// Login to the client
+client.login(process.env.DISCORD_TOKEN).catch((error) => {
+ console.error('Failed to login:', error);
+ process.exit(1);
+});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void client.login(process.env.DISCORD_TOKEN); | |
| // Validate environment variable | |
| if (!process.env.DISCORD_TOKEN) { | |
| throw new Error('Missing required environment variable: DISCORD_TOKEN must be set.'); | |
| } | |
| // Login to the client | |
| client.login(process.env.DISCORD_TOKEN).catch((error) => { | |
| console.error('Failed to login:', error); | |
| process.exit(1); | |
| }); |
🤖 Prompt for AI Agents
In packages/create-discord-bot/template/Bun/TypeScript/src/index.ts around line
24, the code calls client.login(process.env.DISCORD_TOKEN) without validating
the env var and discards the returned promise with void; change this to first
validate that process.env.DISCORD_TOKEN is present and otherwise log an error
and exit, then await the login promise inside a try/catch (or use .catch) so
login failures are handled: on success continue, on failure log the error and
exit with non-zero status. Ensure the function is async or the top-level handles
the promise so you don't drop the returned promise.
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN!); | ||
| const api = new API(rest); | ||
|
|
||
| const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID!, commandData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check Node.js templates for env var handling patterns
echo "=== Node.js TypeScript template ==="
rg -n "process\.env\." packages/create-discord-bot/template/TypeScript/src/util/deploy.ts 2>/dev/null || echo "File not found or no matches"
echo ""
echo "=== Node.js JavaScript template ==="
rg -n "process\.env\." packages/create-discord-bot/template/JavaScript/src/util/deploy.js 2>/dev/null || echo "File not found or no matches"
echo ""
echo "=== Bun TypeScript template (for comparison) ==="
rg -n "process\.env\." packages/create-discord-bot/template/Bun/TypeScript/src/util/deploy.ts 2>/dev/null || echo "File not found or no matches"Repository: discordjs/discord.js
Length of output: 184
Add explicit validation for environment variables with clear error messages.
Non-null assertions on process.env.DISCORD_TOKEN and process.env.APPLICATION_ID will cause cryptic errors if these required variables are missing at runtime. Validating upfront and throwing descriptive errors improves developer experience:
+const token = process.env.DISCORD_TOKEN;
+const applicationId = process.env.APPLICATION_ID;
+
+if (!token) {
+ throw new Error('DISCORD_TOKEN environment variable is required');
+}
+
+if (!applicationId) {
+ throw new Error('APPLICATION_ID environment variable is required');
+}
+
-const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN!);
+const rest = new REST({ version: '10' }).setToken(token);
const api = new API(rest);
-const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID!, commandData);
+const result = await api.applicationCommands.bulkOverwriteGlobalCommands(applicationId, commandData);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN!); | |
| const api = new API(rest); | |
| const result = await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID!, commandData); | |
| const token = process.env.DISCORD_TOKEN; | |
| const applicationId = process.env.APPLICATION_ID; | |
| if (!token) { | |
| throw new Error('DISCORD_TOKEN environment variable is required'); | |
| } | |
| if (!applicationId) { | |
| throw new Error('APPLICATION_ID environment variable is required'); | |
| } | |
| const rest = new REST({ version: '10' }).setToken(token); | |
| const api = new API(rest); | |
| const result = await api.applicationCommands.bulkOverwriteGlobalCommands(applicationId, commandData); |
🤖 Prompt for AI Agents
In packages/create-discord-bot/template/Bun/TypeScript/src/util/deploy.ts around
lines 10 to 13, the code uses non-null assertions on process.env.DISCORD_TOKEN
and process.env.APPLICATION_ID which lead to cryptic runtime errors if those env
vars are missing; instead, read these values into well-named constants,
explicitly check each for presence at startup, and throw clear, descriptive
Errors (or log and exit) indicating which variable is missing and what value is
required before creating the REST/API instances and calling
bulkOverwriteGlobalCommands so failures surface with actionable messages.
| /** | ||
| * Loads all the structures in the provided directory | ||
| * | ||
| * @param dir - The directory to load the structures from | ||
| * @param predicate - The predicate to check if the structure is valid | ||
| * @param recursive - Whether to recursively load the structures in the directory | ||
| * @returns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Minor: Incomplete JSDoc @returns tag.
The @returns tag on line 19 is missing its description.
* @param dir - The directory to load the structures from
* @param predicate - The predicate to check if the structure is valid
* @param recursive - Whether to recursively load the structures in the directory
- * @returns
+ * @returns The loaded structures that satisfy the predicate
*/📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * Loads all the structures in the provided directory | |
| * | |
| * @param dir - The directory to load the structures from | |
| * @param predicate - The predicate to check if the structure is valid | |
| * @param recursive - Whether to recursively load the structures in the directory | |
| * @returns | |
| /** | |
| * Loads all the structures in the provided directory | |
| * | |
| * @param dir - The directory to load the structures from | |
| * @param predicate - The predicate to check if the structure is valid | |
| * @param recursive - Whether to recursively load the structures in the directory | |
| * @returns The loaded structures that satisfy the predicate | |
| */ |
🤖 Prompt for AI Agents
packages/create-discord-bot/template/Bun/TypeScript/src/util/loaders.ts around
lines 13 to 19: the JSDoc block for the function has an empty `@returns` tag;
update it to describe what the function returns (e.g., an array of loaded
structures or a Promise resolving to that array) and include the return
type/shape and any relevant detail about when it resolves/rejects so the
documentation is complete and accurate.
Closes #11346
This PR implements Bun templates for the create-discord-bot package:
The templates include:
src/index.ts/src/index.js- Main bot entry pointsrc/util/deploy.ts/src/util/deploy.js- Command deployment utilitypackage.jsonwith Bun-specific scripts