feat: remove automatic code detection and reformatting feature#30
Conversation
Summary by BeetleThis PR focuses on improving the bot's command reliability and removing an automatic feature that may have caused user friction. The changes include enhanced error handling for the 📁 File Changes Summary (Consolidated across all commits):
Total Changes: 6 files changed, +16 additions, -236 deletions 🗺️ Walkthrough:sequenceDiagram
participant User
participant Discord
participant ManCommand
participant ManAPI
User->>Discord: ";man"
Discord->>ManCommand: Execute command
ManCommand->>ManCommand: Validate term argument
alt No term provided
ManCommand->>Discord: "Missing Term" error embed
Discord->>User: Error message
else Term provided
ManCommand->>ManAPI: Fetch man page
alt Page not found
ManAPI-->>ManCommand: null
ManCommand->>Discord: "Man Page Not Found" embed
Discord->>User: Not found message
else Page found
ManAPI-->>ManCommand: Page data
ManCommand->>Discord: Formatted man page embed
Discord->>User: Man page content
end
Note over User,ManAPI: Automatic code detection removed Messages no longer intercepted
🎯 Key Changes:
📊 Impact Assessment:
⚙️ SettingsSeverity Threshold: 📖 User Guide
|
| // }; | ||
| const page = await man(args.join(" ")); | ||
| if (!page) { | ||
| const term = args[0]; |
There was a problem hiding this comment.
This change breaks support for multi-word man page terms. The original code used args.join(" ") to handle terms like "git commit" or "docker compose", but the new code only uses args[0], which would only capture the first word.
Example of broken behavior:
- User input:
!man git commit - Old behavior: Searches for "git commit" ✅
- New behavior: Searches for "git" only ❌
Confidence: 5/5
Suggested Fix
| const term = args[0]; | |
| const term = args.join(" "); | |
Change args[0] back to args.join(" ") to preserve the original multi-word term support. The validation check if (!term) will still work correctly because args.join(" ") returns an empty string when the array is empty, which is falsy.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/docs/man.ts at line 25, the code currently uses args[0] which only
captures the first word of the man page term, breaking support for multi-word terms
like "git commit" or "docker compose". Change it to args.join(" ") to restore the
original behavior while keeping the improved error handling. The validation check
if (!term) will still work correctly because join returns an empty string for empty
arrays, which is falsy.
|
Note Linting checks passed successfully 🎉 All formatting and code quality checks are clean. You're good to merge 🚀 |
Summary by BeetleThis PR introduces a new 📁 File Changes Summary (Consolidated across all commits):
Total Changes: 5 files changed, +148 additions, -28 deletions 🗺️ Walkthrough:sequenceDiagram
participant User
participant Bot
participant CratesIO as crates.io API
participant PyPI as PyPI API
participant NPM as npm Registry
User->>Bot: ;crate tokio
Bot->>CratesIO: GET /api/v1/crates?q=tokio
CratesIO-->>Bot: Crate metadata
Bot->>Bot: Format embed with standardized fields
Note over Bot: Version, Publisher, Recent Downloads, Repository, License
Bot-->>User: Embed + Action Buttons
User->>Bot: ;pip requests
Bot->>PyPI: GET /pypi/{package}/json
PyPI-->>Bot: Package metadata
Bot->>Bot: Format with same field order
Bot-->>User: Consistent embed layout
User->>Bot: ;npm express
Bot->>NPM: GET /{package}
NPM-->>Bot: Package metadata
Bot->>Bot: Apply standardized formatting
Bot-->>User: Unified user experience
🎯 Key Changes:
📊 Impact Assessment:
⚙️ SettingsSeverity Threshold: 📖 User Guide
|
Summary by BeetleThis PR introduces several improvements to the Quillbot Discord bot, focusing on command enhancements and feature cleanup. The changes include improved error handling for the 📁 File Changes Summary (Consolidated across all commits):
Total Changes: 10 files changed, +163 additions, -264 deletions 🗺️ Walkthrough:graph TD
A["User sends ;crate tokio"] --> B["crate.ts command handler"]
B --> C["Fetch from crates.io API"]
C --> D{"Crate found?"}
D -->|"No"| E["Return 'No crates found' message"]
D -->|"Yes"| F["Extract crate metadata"]
F --> G["Build embed with fields"]
G --> H["Add version, downloads, license"]
H --> I["Create action buttons"]
I --> J["Add crates.io link"]
J --> K{"Homepage exists?"}
K -->|"Yes"| L["Add homepage button"]
K -->|"No"| M["Skip homepage button"]
L --> N["Send embed with buttons"]
M --> N
O["User sends ;man without args"] --> P["man.ts validation"]
P --> Q{"Term provided?"}
Q -->|"No"| R["Return 'Missing Term' error"]
Q -->|"Yes"| S["Fetch man page"]
S --> T{"Page found?"}
T -->|"No"| U["Return 'Man Page Not Found' error"]
T -->|"Yes"| V["Display man page embed"]
style B fill:#4CAF50
style F fill:#2196F3
style P fill:#FF9800
style G fill:#2196F3
🎯 Key Changes:
📊 Impact Assessment:
⚙️ SettingsSeverity Threshold: 📖 User Guide
|
|
✅ You're good to merge this PR! No issues found. Great job! Settings⚙️ SettingsSeverity Threshold: 📖 User Guide
|
|
Note Linting checks passed successfully 🎉 All formatting and code quality checks are clean. You're good to merge 🚀 |
| const searchRes = await fetch( | ||
| `https://crates.io/api/v1/crates?q=${encodeURIComponent(query)}&per_page=1`, | ||
| { | ||
| headers: { "User-Agent": "DiscordBot (contact@yourbotdomain.com)" }, | ||
| }, | ||
| ); | ||
| const searchData = await searchRes.json(); |
There was a problem hiding this comment.
The code doesn't validate the HTTP response status before attempting to parse JSON. If the crates.io API returns an error status (4xx, 5xx), calling .json() on a non-JSON response will throw an exception that gets caught generically, hiding the actual API error from users.
Confidence: 5/5
Suggested Fix
| const searchRes = await fetch( | |
| `https://crates.io/api/v1/crates?q=${encodeURIComponent(query)}&per_page=1`, | |
| { | |
| headers: { "User-Agent": "DiscordBot (contact@yourbotdomain.com)" }, | |
| }, | |
| ); | |
| const searchData = await searchRes.json(); | |
| const searchRes = await fetch( | |
| `https://crates.io/api/v1/crates?q=${encodeURIComponent(query)}&per_page=1`, | |
| { | |
| headers: { "User-Agent": "DiscordBot (contact@yourbotdomain.com)" }, | |
| }, | |
| ); | |
| if (!searchRes.ok) { | |
| return message.reply(`Failed to fetch crate data: ${searchRes.status} ${searchRes.statusText}`); | |
| } | |
| const searchData = await searchRes.json(); | |
Add HTTP response status validation after the fetch call and before parsing JSON. This prevents attempting to parse error HTML/text responses as JSON and provides clearer error messages to users.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/search/crate.ts around line 25-31, the fetch call to crates.io API doesn't validate the HTTP response status before calling .json(). Add a check for searchRes.ok after line 30 and before line 31, and return an appropriate error message if the response status indicates failure (4xx or 5xx). This prevents JSON parsing errors when the API returns non-JSON error responses.
📍 This suggestion applies to lines 25-31
| ); | ||
| } | ||
|
|
||
| const row = new ActionRowBuilder().addComponents(...componentButtons); |
There was a problem hiding this comment.
The ActionRowBuilder is instantiated without a generic type parameter, which will cause TypeScript compilation errors or runtime issues when calling .toJSON(). Discord.js v14+ requires explicit typing for ActionRowBuilder components.
Confidence: 5/5
Suggested Fix
| const row = new ActionRowBuilder().addComponents(...componentButtons); | |
| const row = new ActionRowBuilder<ButtonBuilder>().addComponents(...componentButtons); | |
Add the generic type parameter <ButtonBuilder> to ActionRowBuilder to ensure type safety and prevent runtime errors when converting to JSON.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/search/crate.ts at line 113, the ActionRowBuilder is missing its generic type parameter. Add <ButtonBuilder> after ActionRowBuilder to properly type the component row, which is required for Discord.js v14+ and prevents type errors when calling .toJSON().
Summary by BeetleThis PR introduces a new 📁 File Changes Summary (Consolidated across all commits):
Total Changes: 3 files changed, +143 additions, -0 deletions 🗺️ Walkthrough:sequenceDiagram
participant User
participant Discord
participant GemCommand
participant RubyGemsAPI
User->>Discord: ;gem rails
Discord->>GemCommand: Execute command with args
alt No query provided
GemCommand->>User: Error: "Please provide a search term"
else Query provided
GemCommand->>RubyGemsAPI: GET /api/v1/search.json?query=rails
alt API Error
RubyGemsAPI-->>GemCommand: Error response
GemCommand->>User: Error embed
else Success
RubyGemsAPI-->>GemCommand: JSON array of gems
alt No results
GemCommand->>User: "No Ruby gems found"
else Results found
GemCommand->>GemCommand: Format first result
Note over GemCommand: Extract metadata: version, author, downloads, repository, license
GemCommand->>GemCommand: Build embed & buttons
GemCommand->>User: Rich embed with gem details + action buttons
end
🎯 Key Changes:
📊 Impact Assessment:
⚙️ SettingsSeverity Threshold: 📖 User Guide
|
| const searchRes = await fetch( | ||
| `https://rubygems.org/api/v1/search.json?query=${encodeURIComponent(query)}`, | ||
| ); |
There was a problem hiding this comment.
The fetch request lacks a timeout, which can cause the Discord bot to hang indefinitely if the RubyGems API is slow or unresponsive. This can lead to resource exhaustion and poor user experience.
Confidence: 5/5
Suggested Fix
| const searchRes = await fetch( | |
| `https://rubygems.org/api/v1/search.json?query=${encodeURIComponent(query)}`, | |
| ); | |
| const controller = new AbortController(); | |
| const timeoutId = setTimeout(() => controller.abort(), 10000); | |
| const searchRes = await fetch( | |
| `https://rubygems.org/api/v1/search.json?query=${encodeURIComponent(query)}`, | |
| { signal: controller.signal } | |
| ); | |
| clearTimeout(timeoutId); | |
Add a 10-second timeout to prevent the request from hanging indefinitely. Wrap the fetch in a try-catch to handle AbortError appropriately.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/search/gem.ts around line 23, the fetch request to the RubyGems API lacks a timeout mechanism, which can cause the bot to hang indefinitely if the API is slow or unresponsive; add an AbortController with a 10-second timeout to the fetch request, and handle the AbortError in the catch block to provide a user-friendly timeout message.
📍 This suggestion applies to lines 23-25
| throw new Error("RubyGems API failed to respond properly."); | ||
| } | ||
|
|
||
| const searchData = await searchRes.json(); |
There was a problem hiding this comment.
The searchRes.json() call can throw an error if the API returns invalid JSON, but this isn't caught separately from other errors. This could expose internal error details to users or cause unclear error messages.
Confidence: 5/5
Suggested Fix
| const searchData = await searchRes.json(); | |
| const searchData = await searchRes.json().catch(() => { | |
| throw new Error("Invalid response format from RubyGems API"); | |
| }); | |
Add explicit error handling for JSON parsing failures to provide clearer error messages and prevent exposing internal error details.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/search/gem.ts around line 31, the JSON parsing of the API response can throw an error if the response is malformed, but this isn't handled separately; wrap the json() call in a try-catch or use .catch() to throw a more specific error message like "Invalid response format from RubyGems API" to improve error clarity.
| ); | ||
| } | ||
|
|
||
| const row = new ActionRowBuilder().addComponents(...buttons); |
There was a problem hiding this comment.
ActionRowBuilder requires a generic type parameter in Discord.js v14+. Without it, TypeScript will throw a compilation error, and the toJSON() method may not work correctly.
Confidence: 5/5
Suggested Fix
| const row = new ActionRowBuilder().addComponents(...buttons); | |
| const row = new ActionRowBuilder<ButtonBuilder>().addComponents(...buttons); | |
Add the generic type parameter <ButtonBuilder> to ensure type safety and proper compilation.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/search/gem.ts at line 121, the ActionRowBuilder is missing its required generic type parameter; change it to ActionRowBuilder<ButtonBuilder> to ensure proper TypeScript compilation and type safety with Discord.js v14+.
|
Note Linting checks passed successfully 🎉 All formatting and code quality checks are clean. You're good to merge 🚀 |
No description provided.