Skip to content

feat: Sentry error monitoring integration (#38)#91

Merged
BillChirico merged 9 commits intomainfrom
feat/warning-system
Feb 26, 2026
Merged

feat: Sentry error monitoring integration (#38)#91
BillChirico merged 9 commits intomainfrom
feat/warning-system

Conversation

@BillChirico
Copy link
Collaborator

@BillChirico BillChirico commented Feb 26, 2026

Summary

Integrates Sentry for error tracking, performance monitoring, and alerting via the existing Winston logging pipeline. Every error() and warn() call in the codebase automatically reports to Sentry — zero manual instrumentation needed.

Closes #38

Architecture

Winston Logger
  ├── Console Transport (always)
  ├── File Transport (if configured)
  ├── PostgreSQL Transport (if configured)
  ├── WebSocket Transport (if configured)
  └── Sentry Transport (if SENTRY_DSN set) ← NEW

Single integration point — no Sentry.captureException() calls scattered throughout the codebase. The SentryTransport hooks into Winston and forwards error/warn logs automatically.

Changes

New Files

  • src/sentry.js — Sentry SDK initialization (must be imported first). Configurable via env vars.
  • src/transports/sentry.js — Winston transport that forwards error/warn logs to Sentry with proper tags and stack traces.
  • tests/sentry.test.js — Tests for Sentry module

Modified Files

  • src/logger.js — Adds SentryTransport when SENTRY_DSN is set
  • src/index.js — Imports sentry.js first; adds source tag to error metadata; shard disconnect handler; Sentry flush on shutdown
  • .env.example — Documented Sentry env vars

How It Works

  1. src/sentry.js initializes the Sentry SDK on import (if SENTRY_DSN is set)
  2. src/logger.js adds a SentryTransport to Winston
  3. Any error() or warn() call anywhere in the codebase → automatically captured by Sentry
  4. Metadata keys like source, command, module are promoted to Sentry tags for filtering
  5. Stack traces are reconstructed for proper Sentry error grouping

Error Capture (Automatic via Winston)

Source Log Call Sentry Level
Discord client error error('...', { source: 'discord_client' }) error
Slash command error error('...', { source: 'slash_command', command }) error
Shard disconnect warn('...', { source: 'discord_shard' }) warning
Database pool error error('...', { source: 'database_pool' }) error
API 5xx errors error('Unhandled API error', ...) error
Unhandled rejections Auto-captured by Sentry SDK error
Uncaught exceptions Auto-captured by Sentry SDK fatal

Environment Variables

Variable Required Default Description
SENTRY_DSN No Sentry project DSN. Omit to disable.
SENTRY_ENVIRONMENT No NODE_ENV or production Environment name
SENTRY_TRACES_RATE No 0.1 (10%) Performance sampling rate

Setup

  1. Create a Sentry project at sentry.io → New Project → Node.js
  2. Set SENTRY_DSN in .env
  3. Configure alert rules in Sentry dashboard

Zero-config when disabled — without SENTRY_DSN, the SDK is not initialized and the SentryTransport is not added.

Testing

  • 71 test files, 1476 tests passing, 0 failures

Breaking Changes

None — Sentry is opt-in via env var

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 922660f and 77ffd9a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • .env.example
  • package.json
  • src/db.js
  • src/index.js
  • src/logger.js
  • src/sentry.js
  • src/transports/sentry.js
  • tests/index.test.js
  • tests/sentry.test.js

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Integrated comprehensive error monitoring and performance tracking system (optional, requires configuration).
    • Enhanced error logging throughout the application with improved source attribution for better diagnostics.
  • Documentation

    • Added optional environment configuration variables for error monitoring service and performance tracing rates.

Walkthrough

Integrates Sentry error monitoring throughout the application by introducing a new Sentry initialization module, Winston transport for log forwarding, and source attribution to errors across database, Discord client, and slash command handlers. Includes configuration, dependencies, and comprehensive tests.

Changes

Cohort / File(s) Summary
Sentry Core Module & Tests
src/sentry.js, tests/sentry.test.js
Introduces new Sentry initialization module that conditionally enables error monitoring based on SENTRY_DSN environment variable, with configurable tracing rates and error filtering. Test suite verifies initialization logic and DSN handling.
Logger & Transport Integration
src/logger.js, src/transports/sentry.js
Adds new Winston transport that forwards warn/error logs to Sentry, extracting metadata keys as tags and routing error/warn messages appropriately. Logger integration conditionally adds transport when Sentry is enabled.
Application Error Handling
src/index.js, src/db.js, tests/index.test.js
Adds Sentry initialization and error context setup in index.js startup/shutdown flow. Enriches error logs with source attribution (discord_client, discord_shard, slash_command, database_pool) across modules. Test expectations updated to reflect new source field.
Configuration & Dependencies
package.json, .env.example
Adds @sentry/node v^10.40.0 dependency and Sentry environment variables (SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_TRACES_RATE) to example configuration.

Possibly related PRs

  • PR #91: Introduces identical Sentry integration implementation including src/sentry.js module, package.json dependency, and error source attribution patterns.
  • PR #14: Modifies src/db.js pool error event handling to add source field in error metadata.
  • PR #4: Extends the Winston-based structured logging system with a new transport implementation for external error reporting.
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds Sentry error monitoring but does not implement the comprehensive alerting system with deduplication, persistence, state management, or notification routing required by issue #38. Implement missing alerting features: alert persistence layer, deduplication/fingerprinting, severity classification, state transitions, alert delivery service, cooldowns/burst suppression, and API endpoints for alert management.
Description check ⚠️ Warning The PR description explains Sentry integration via Winston transport, but actual changes show direct Sentry SDK calls in multiple files, contradicting the stated architecture of a single Winston integration point. Clarify whether the implementation uses a Winston SentryTransport (as described) or direct SDK calls. Update description or code to match stated single-integration-point architecture.
Out of Scope Changes check ❓ Inconclusive All changes are directly related to Sentry SDK integration. However, this contradicts the stated objective of implementing a comprehensive alerting system with persistence, dedup, and delivery—those requirements are not addressed in this PR. Clarify whether this PR intentionally delivers only error monitoring without the alerting system, or if critical features are missing and should be added before merge.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat: Sentry error monitoring integration' accurately reflects the main change: integrating Sentry SDK for error tracking across multiple system components.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/warning-system

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@BillChirico BillChirico changed the title feat: comprehensive warning/alerting system (#38) feat: Sentry error monitoring integration (#38) Feb 26, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@migrations/002_alerts-table.cjs`:
- Around line 33-35: The current non-unique index idx_alerts_fingerprint on
alerts(fingerprint) allows concurrent inserts of identical unresolved alerts;
replace it with a partial unique index enforcing uniqueness only for unresolved
rows (e.g., create a UNIQUE INDEX (name it something like
idx_alerts_fingerprint_unresolved_unique) on alerts(fingerprint) WHERE
resolved_at IS NULL) so duplicate unresolved fingerprints are prevented; update
the migration to drop the old non-unique idx_alerts_fingerprint (or include IF
EXISTS) before creating the partial unique index and ensure the index name and
predicate reference the alerts table, fingerprint column, and resolved_at
column.
- Around line 16-21: The migration currently defines severity and state as
free-form TEXT (columns severity and state in the alerts table); add DB-level
constraints by either creating ENUM types or adding CHECK constraints to
restrict allowed values (e.g., severity IN ('low','medium','high') and state IN
('new','acknowledged','resolved')), update the column definitions in
migrations/002_alerts-table.cjs to use those constraints (or use CREATE TYPE ...
AS ENUM then ALTER TABLE to use the enum) and preserve the existing default
'new' for state; ensure the migration includes the corresponding down/revert
steps to drop the enum or constraints when rolling back.

In `@src/services/alertDelivery.js`:
- Around line 102-103: Replace the direct call to user.send(messageOptions) with
the project's safeSend wrapper to ensure mention-sanitization and
allowedMentions enforcement: locate the try block in
src/services/alertDelivery.js where user.send(messageOptions) is invoked and
change it to call safeSend(user, messageOptions) (or the appropriate safeSend
signature used elsewhere), importing/using the existing safeSend utility if not
already imported, and keep the same await/try/catch flow so error handling
around send remains unchanged.

In `@src/services/alertService.js`:
- Around line 274-278: The unconditional UPDATE can overwrite terminal/acked
states; change the query that currently calls pool.query(`UPDATE alerts SET
state = 'sent', sent_at = NOW() WHERE id = $1`, [alert.id]) to a guarded update
that only sets state='sent' when the current state is not a terminal or
acknowledged state (e.g., add "AND state NOT IN ('acked','resolved')" or your
app's terminal state names). Keep the same parameters (alert.id), and consider
using the returned rowCount/RETURNING to detect whether the update occurred so
callers (in this module where getPool() and the pool.query(...) call live) can
handle the case where the state was already terminal.
- Around line 21-22: The global cooldowns Map is unbounded and will leak memory;
change its usage to store expiry timestamps (e.g., cooldowns.set(key,
expiresAt)) and enforce TTL eviction by (a) checking and deleting expired
entries on access in whatever functions consult it (e.g., the methods that
check/add cooldowns) and (b) adding a periodic cleanup (setInterval) that scans
cooldowns and deletes entries older than the TTL; also cap total size (optional)
and ensure the cleanup interval is cleared on shutdown to avoid timers leaking.
Ensure all references to the cooldowns Map (insertions, reads, deletions) are
updated to use the expiry value semantics so entries are removed when expired.
- Around line 64-65: The logger calls in alertService use bare messages (e.g.,
info('Alert service initialized')) and should pass minimal structured metadata
for consistency; update those info/error calls in this module (including the
call that logs "Alert service initialized" and the other occurrences around the
later startup/shutdown and runtime log points) to include a metadata object such
as { service: 'alertService', component: '<componentName>' } (or at least {
service: 'alertService' }) so every Winston call follows the pattern
info('message', { ...metadata }) for easier filtering and observability.
- Around line 210-247: The current SELECT-then-INSERT/UPDATE flow is racey;
replace it with a single atomic upsert using the alerts unique constraint on
unresolved fingerprint so concurrent ingests cannot create duplicates. Implement
an INSERT ... ON CONFLICT (fingerprint) WHERE state != 'resolved' DO UPDATE that
increments count, sets last_seen = NOW(), updates severity to the
higher/more-recent effectiveSeverity, merges payload (payload = alerts.payload
|| $payload::jsonb), and RETURNING * so the code uses the returned row as alert
(replace the existing pool.query SELECT + conditional INSERT/UPDATE logic around
fingerprint/effectiveSeverity/payload/correlationId/guildId). Keep the
subsequent notification logic (isNew determination, NOTIFY_THRESHOLDS check,
isNotificationAllowed) but derive isNew from whether the returned row was
created or updated (e.g., compare returned count or use INSERT ... RETURNING to
indicate insertion) rather than the prior separate SELECT.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3781ac and adb6f29.

📒 Files selected for processing (11)
  • migrations/002_alerts-table.cjs
  • src/api/index.js
  • src/api/routes/alerts.js
  • src/api/server.js
  • src/db.js
  • src/index.js
  • src/services/alertDelivery.js
  • src/services/alertService.js
  • tests/api/routes/alerts.test.js
  • tests/services/alertDelivery.test.js
  • tests/services/alertService.test.js
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules only — use import/export, never require()
Use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons
Use single quotes for strings
Use 2-space indentation
No TypeScript — use plain JavaScript with JSDoc comments for documentation

Files:

  • src/api/server.js
  • tests/services/alertService.test.js
  • src/api/routes/alerts.js
  • tests/api/routes/alerts.test.js
  • src/index.js
  • src/db.js
  • src/services/alertDelivery.js
  • src/services/alertService.js
  • tests/services/alertDelivery.test.js
  • src/api/index.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston for logging — import { info, warn, error } from ../logger.js
NEVER use console.log, console.warn, console.error, or any console.* method in src/ files
Pass structured metadata to Winston logging calls (e.g. info('Message processed', { userId, channelId }))
Use custom error classes from src/utils/errors.js for error handling
Always log errors with context before re-throwing
Use getConfig(guildId?) from src/modules/config.js to read config
Use setConfigValue(path, value, guildId?) from src/modules/config.js to update config at runtime
Use splitMessage() utility for messages exceeding Discord's 2000-character limit
Use safeSend() wrapper for outgoing Discord messages to sanitize mentions and enforce allowedMentions

Files:

  • src/api/server.js
  • src/api/routes/alerts.js
  • src/index.js
  • src/db.js
  • src/services/alertDelivery.js
  • src/services/alertService.js
  • src/api/index.js
tests/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Test files must achieve at least 80% code coverage on statements, branches, functions, and lines

Files:

  • tests/services/alertService.test.js
  • tests/api/routes/alerts.test.js
  • tests/services/alertDelivery.test.js
🧬 Code graph analysis (11)
src/api/server.js (1)
src/services/alertService.js (1)
  • ingestAlert (162-258)
tests/services/alertService.test.js (3)
src/services/alertService.js (13)
  • shutdownAlertService (70-74)
  • initAlertService (62-65)
  • generateFingerprint (83-87)
  • VALID_SOURCES (41-41)
  • VALID_CATEGORIES (46-46)
  • VALID_SEVERITIES (51-51)
  • VALID_STATES (56-56)
  • ingestAlert (162-258)
  • ackAlert (293-309)
  • resolveAlert (316-332)
  • getActiveAlerts (343-375)
  • alert (217-217)
  • getAlertById (382-391)
src/db.js (1)
  • getPool (303-308)
src/api/routes/alerts.js (1)
  • alerts (26-31)
migrations/002_alerts-table.cjs (1)
src/services/alertService.js (6)
  • pool (199-199)
  • pool (274-274)
  • pool (295-295)
  • pool (318-318)
  • pool (345-345)
  • pool (384-384)
src/api/routes/alerts.js (1)
src/services/alertService.js (4)
  • getActiveAlerts (343-375)
  • getAlertById (382-391)
  • ackAlert (293-309)
  • resolveAlert (316-332)
tests/api/routes/alerts.test.js (2)
src/api/routes/alerts.js (1)
  • alerts (26-31)
src/services/alertService.js (5)
  • getActiveAlerts (343-375)
  • getAlertById (382-391)
  • alert (217-217)
  • ackAlert (293-309)
  • resolveAlert (316-332)
src/index.js (1)
src/services/alertService.js (3)
  • shutdownAlertService (70-74)
  • ingestAlert (162-258)
  • initAlertService (62-65)
src/db.js (1)
src/services/alertService.js (1)
  • ingestAlert (162-258)
src/services/alertDelivery.js (3)
src/services/alertService.js (1)
  • alert (217-217)
src/logger.js (1)
  • warn (230-232)
src/modules/config.js (1)
  • err (94-94)
src/services/alertService.js (2)
src/logger.js (2)
  • info (223-225)
  • warn (230-232)
src/db.js (1)
  • getPool (303-308)
tests/services/alertDelivery.test.js (1)
src/services/alertDelivery.js (1)
  • sendAlertDM (62-108)
src/api/index.js (1)
src/api/middleware/auth.js (1)
  • requireAuth (36-70)
🔇 Additional comments (8)
src/api/index.js (1)

23-24: Alerts endpoints are correctly protected.

Mounting /alerts behind requireAuth() matches the intended auth model.

tests/services/alertDelivery.test.js (1)

46-147: Solid behavioral coverage for alert DM delivery.

The suite covers success path, failure modes, severity rendering, and payload shaping well.

src/api/routes/alerts.js (1)

41-44: File does not exist in the repository.

The file src/api/routes/alerts.js does not exist. The repository contains only the following API route files: auth.js, config.js, guilds.js, health.js, and webhooks.js. This review cannot be applied to the current codebase.

Likely an incorrect or invalid review comment.

src/api/server.js (1)

80-90: The code snippet in this review does not exist in the repository. The file src/api/server.js at lines 80-90 contains standard error logging with the error() function, not the alertService pattern described in the review comment. Additionally, neither alertService, ingestAlert, nor the referenced .catch(() => {}) pattern exists anywhere in the codebase for this file.

Likely an incorrect or invalid review comment.

src/db.js (1)

80-92: Code snippet does not match src/db.js — review references non-existent alertService integration.

The code at lines 80–92 in src/db.js uses Sentry error reporting, not an alertService with ingestAlert(). The code referenced in the review comment (import('./services/alertService.js'), ingestAlert({ source: 'db', ... })) does not exist in the codebase.

The actual error handling at those lines already logs via logError() (line 77) and captures exceptions via Sentry (lines 80–84), with the .catch(() => {}) silently swallowing Sentry import failures.

Likely an incorrect or invalid review comment.

src/index.js (1)

315-324: This review comment references code that does not exist in the repository.

No uncaughtException handler or ingestAlert() function exists in the codebase. Lines 315-324 of src/index.js contain Discord client error handlers that already use Winston logging (error()) and Sentry exception capture. Unhandled exceptions are automatically captured by Sentry (configured with autoSessionTracking: true), and graceful shutdown is handled via existing SIGTERM/SIGINT handlers that call gracefulShutdown().

Likely an incorrect or invalid review comment.

tests/api/routes/alerts.test.js (1)

49-208: Good endpoint-behavior coverage for auth, filters, and transition outcomes.

This suite is well-scoped for the new /api/v1/alerts GET/PATCH contract and catches key validation/error paths.

tests/services/alertService.test.js (1)

94-535: Comprehensive ingest/lifecycle test coverage for the new service API.

The suite exercises core alert flows and major failure paths with clear mocks and assertions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/sentry.js`:
- Around line 32-34: Update the misleading comment above the Sentry
configuration where autoSessionTracking is set (the block including
autoSessionTracking: true) to reference the correct SDK version used in the
project (e.g., `@sentry/node` v10) or remove the version-specific mention; edit
the comment text to say that current Sentry SDK (v10) handles unhandled
rejections/uncaught exceptions by default or simply state that explicit handling
is being kept for clarity.
- Around line 29-30: The tracesSampleRate fallback uses || which treats 0 as
falsy and prevents explicitly setting 0; update the assignment for
tracesSampleRate (currently using parseFloat(process.env.SENTRY_TRACES_RATE) ||
0.1) to properly allow 0 by first parsing the env var into a numeric value, then
use nullish/NaN-safe logic (e.g. let rate =
parseFloat(process.env.SENTRY_TRACES_RATE); tracesSampleRate =
Number.isFinite(rate) ? rate : 0.1) so that 0 is preserved but invalid/absent
values default to 0.1.

In `@tests/sentry.test.js`:
- Around line 7-34: Add edge-case tests for configuration parsing in
tests/sentry.test.js: add a test that stubs SENTRY_TRACES_RATE=0 to assert the
module handles a zero traces rate correctly (import ../src/sentry.js and assert
sentryEnabled and that the tracesSampleRate used by Sentry.init is 0 via the
Sentry mock), and add a test that stubs SENTRY_ENVIRONMENT and NODE_ENV to
verify that SENTRY_ENVIRONMENT takes precedence over NODE_ENV (stub SENTRY_DSN,
set SENTRY_ENVIRONMENT='staging' and NODE_ENV='development', import
../src/sentry.js, assert sentryEnabled and that Sentry.init was called with
environment 'staging'); reference the Sentry.init call and the
SENTRY_TRACES_RATE / SENTRY_ENVIRONMENT / NODE_ENV env vars when wiring the
Sentry mock.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adb6f29 and 922660f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .env.example
  • package.json
  • src/api/server.js
  • src/db.js
  • src/index.js
  • src/sentry.js
  • tests/sentry.test.js
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules only — use import/export, never require()
Use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons
Use single quotes for strings
Use 2-space indentation
No TypeScript — use plain JavaScript with JSDoc comments for documentation

Files:

  • src/db.js
  • src/sentry.js
  • src/api/server.js
  • src/index.js
  • tests/sentry.test.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston for logging — import { info, warn, error } from ../logger.js
NEVER use console.log, console.warn, console.error, or any console.* method in src/ files
Pass structured metadata to Winston logging calls (e.g. info('Message processed', { userId, channelId }))
Use custom error classes from src/utils/errors.js for error handling
Always log errors with context before re-throwing
Use getConfig(guildId?) from src/modules/config.js to read config
Use setConfigValue(path, value, guildId?) from src/modules/config.js to update config at runtime
Use splitMessage() utility for messages exceeding Discord's 2000-character limit
Use safeSend() wrapper for outgoing Discord messages to sanitize mentions and enforce allowedMentions

Files:

  • src/db.js
  • src/sentry.js
  • src/api/server.js
  • src/index.js
tests/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Test files must achieve at least 80% code coverage on statements, branches, functions, and lines

Files:

  • tests/sentry.test.js
🧠 Learnings (3)
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/**/*.js : Always use Winston for logging — import `{ info, warn, error }` from `../logger.js`

Applied to files:

  • src/api/server.js
  • src/index.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/**/*.js : Use `safeSend()` wrapper for outgoing Discord messages to sanitize mentions and enforce allowedMentions

Applied to files:

  • src/index.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/commands/*.js : Slash commands must export both `data` (SlashCommandBuilder) and `execute(interaction)` function

Applied to files:

  • src/index.js
🔇 Additional comments (10)
.env.example (1)

103-113: LGTM!

The Sentry configuration section is well-documented with clear comments explaining each variable's purpose, default values, and where to obtain the DSN. The format is consistent with the rest of the file.

src/sentry.js (1)

36-44: LGTM on the beforeSend filter.

Filtering out AbortError and intentional request cancellations is a sensible noise reduction strategy that prevents expected errors from consuming Sentry quota.

src/db.js (1)

80-85: LGTM!

The lazy dynamic import pattern correctly avoids circular dependencies while still enabling Sentry error reporting for database pool errors. The error is already logged via Winston before the Sentry capture, so the empty .catch(() => {}) is acceptable here since a failure to report to Sentry shouldn't prevent normal error handling.

src/index.js (5)

14-15: LGTM — correct import order for Sentry instrumentation.

Importing Sentry before other application modules ensures proper instrumentation. The comment clearly explains this requirement.


225-230: LGTM — comprehensive error context for slash commands.

The Sentry capture includes useful context: source tag for filtering, command name for debugging, and user information for tracing issues to specific interactions.


295-298: LGTM — proper Sentry flush before shutdown.

The 2-second timeout for Sentry.flush() is reasonable and the .catch(() => {}) ensures shutdown isn't blocked if flushing fails. Placing this before client.destroy() ensures events are sent while the process is still running.


320-334: LGTM — appropriate error and warning capture for Discord events.

Good separation of concerns:

  • Client errors captured as exceptions (appropriate for unexpected errors)
  • Shard disconnects with non-1000 codes captured as warnings (appropriate since they may be transient)

454-459: LGTM — useful runtime context tags.

Setting bot.username and bot.version tags after login provides valuable context for debugging production issues. The info log confirms Sentry is active.

package.json (1)

22-22: No action needed. @sentry/node@10.40.0 is the latest published version and has Node.js engine requirements (>=18) that match the project's minimum Node.js version.

src/api/server.js (1)

66-69: LGTM — correct placement of Sentry error handler.

The Sentry error handler is correctly placed after route mounting but before the custom error middleware. This ensures Sentry captures errors while still allowing the custom middleware to handle the response. The @sentry/node v10 setupExpressErrorHandler() is compatible with Express 5.x and the integration follows the documented best practices.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #92

coderabbitai bot added a commit that referenced this pull request Feb 26, 2026
Docstrings generation was requested by @BillChirico.

* #91 (comment)

The following files were modified:

* `src/db.js`
* `src/index.js`
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Note

Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

BillChirico pushed a commit that referenced this pull request Feb 26, 2026
Docstrings generation was requested by @BillChirico.

* #91 (comment)

The following files were modified:

* `src/db.js`
* `src/index.js`
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 26, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Request timed out after 900000ms (requestId=b5220cb1-e712-402d-ad54-d33035ca3881)

…ption calls

- Created SentryTransport (src/transports/sentry.js) that forwards error/warn logs to Sentry
- Added transport to logger.js — single integration point
- Removed all manual if(sentryEnabled) checks from index.js, server.js, db.js
- Metadata 'source', 'command', 'module' auto-promoted to Sentry tags
- Stack traces reconstructed for proper Sentry grouping
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bill-bot: comprehensive warning system

1 participant