Complete guide for setting up centralized error monitoring with Sentry across the LearnVault backend (Express) and frontend (React).
- Overview
- Prerequisites
- Sentry Project Setup
- Backend Setup (Express)
- Frontend Setup (React)
- Environment Configuration
- Release Tracking
- PII Scrubbing
- Deployment
- Verification
- Troubleshooting
This implementation provides:
- Backend (Express): Full error capture with request context, automatic performance tracing
- Frontend (React): Error boundary integration, automatic breadcrumb tracking, session replay
- PII Protection: Automatic redaction of wallet addresses (
0x[a-fA-F0-9]{40}) from all payloads - Release Tracking: Correlation of errors with git commit hashes for deployment tracking
- Environment Support: Separate configurations for dev, staging, and production
- Node.js 18+ and npm
- Sentry account with organization access
- Access to deploy both frontend and backend applications
- Log in to Sentry
- Create two projects under your organization:
learnvault-frontend(platform: React)learnvault-backend(platform: Node.js)
For each project:
- Navigate to Settings → Projects → [project-name] → Keys
- Copy the DSN (Data Source Name)
- Save both DSNs securely
- Go to Settings → General
- Enable Require HTTPS for production
- Configure Data Scrubbing (additional layer beyond our custom scrubbing)
- Set up Teams and Access Control as needed
The Sentry SDK has already been added to server/package.json:
cd server
npm installRequired packages:
@sentry/node- Core Node.js SDK@sentry/profiling-node- Performance profiling
-
server/src/lib/sentry.ts- Sentry initialization and configuration- PII scrubbing with wallet address redaction
- Request context enrichment
- User context management
-
server/src/middleware/error.middleware.ts- Updated error handler- Captures errors to Sentry with appropriate severity levels
- Includes request context (path, method, requestId)
-
server/src/index.ts- Main entry point- Sentry initialization at startup
- Request handler middleware integration
import { setSentryUser, captureError } from "../lib/sentry"
// After authentication
setSentryUser(userId, email, walletAddress)
// Manual error capture with context
try {
// ... risky operation
} catch (error) {
captureError(error, {
level: "error",
tags: { feature: "milestone-approval" },
extra: { milestoneId, amount }
})
}The Sentry SDK has already been added to package.json:
npm installRequired packages:
@sentry/react- React integration@sentry/browser- Browser utilities
-
src/lib/sentry.ts- Sentry initialization and configuration- PII scrubbing with wallet address redaction
- React integration with component tracking
- Session replay configuration
- Redux enhancer (optional)
-
src/main.tsx- App entry point- Sentry initialization before React render
- Environment-based configuration
import { captureError, addBreadcrumb, setSentryUser } from "./lib/sentry"
// After wallet connection
setSentryUser(userId, email, walletAddress)
// Manual error capture
const handleError = (error: Error) => {
captureError(error, {
tags: { component: "MilestoneForm" },
extra: { formData }
})
}
// Add breadcrumbs for context
addBreadcrumb("User clicked submit button", "ui", "info", { formId })For additional React error catching, wrap your app:
import { ErrorBoundary } from "@sentry/react"
<ErrorBoundary
fallback={<div>Error occurred</div>}
onError={(error) => captureError(error)}
>
<App />
</ErrorBoundary># Copy from .env.example
cp .env.example .env
# Add Sentry configuration
VITE_SENTRY_DSN=https://xxx@oXXX.ingest.sentry.io/XXX
VITE_SENTRY_ENVIRONMENT=production
VITE_SENTRY_TRACES_SAMPLE_RATE=0.1
VITE_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=0.1
VITE_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=1.0# Copy from server/.env.example
cp server/.env.example server/.env
# Add Sentry configuration
SENTRY_DSN=https://xxx@oXXX.ingest.sentry.io/XXX
SENTRY_ENVIRONMENT=production
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0.1| Environment | Traces Sample Rate | Replay Session Rate | Notes |
|---|---|---|---|
| Development | 1.0 | 0.0 | Full tracing for debugging |
| Staging | 0.5 | 0.1 | Moderate sampling |
| Production | 0.1 | 0.1 | Low sampling to manage quota |
Sentry can automatically detect releases from your CI/CD pipeline.
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get Git Commit Hash
id: git
run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Set Sentry Release (Frontend)
run: |
echo "VITE_SENTRY_RELEASE=${{ steps.git.outputs.COMMIT_HASH }}" >> .env
echo "VITE_GIT_COMMIT_HASH=${{ steps.git.outputs.COMMIT_HASH }}" >> .env
- name: Set Sentry Release (Backend)
run: |
echo "SENTRY_RELEASE=${{ steps.git.outputs.COMMIT_HASH }}" >> server/.env
echo "GIT_COMMIT_HASH=${{ steps.git.outputs.COMMIT_HASH }}" >> server/.env
- name: Build and Deploy
run: |
npm ci
npm run build
# ... deploy steps
- name: Create Sentry Release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: your-org
SENTRY_PROJECT: learnvault-backend
with:
environment: production
version: ${{ steps.git.outputs.COMMIT_HASH }}# Install Sentry CLI
npm install -g @sentry/cli
# Authenticate
sentry login
# Create release
sentry releases new -p learnvault-backend <commit-hash>
# Set commits for the release
sentry releases set-commits <commit-hash> --auto
# Deploy mark
sentry releases deploys <commit-hash> new -e productionThe implementation automatically redacts:
-
Wallet Addresses: Any string matching
0x[a-fA-F0-9]{40}- Replaced with
[REDACTED_WALLET] - Applied to error messages, stack traces, breadcrumbs, contexts
- Replaced with
-
Sensitive Fields: Automatically excluded from request bodies
- Fields containing:
password,secret,token,private
- Fields containing:
Both frontend and backend implement beforeSend filters:
// Pattern used for wallet address detection
const WALLET_ADDRESS_REGEX = /0x[a-fA-F0-9]{40}/g
// Applied to all error events before sending to Sentry
function scrubPII(event: Sentry.Event): Sentry.Event {
// Redacts from:
// - Exception messages
// - Stack trace variables
// - Breadcrumbs
// - Context data
// - User context (preserves ID, redacts wallet)
return event
}For defense in depth, configure Sentry's built-in scrubbing:
- Go to Settings → Projects → [project] → Security & Privacy
- Enable Data Scrubbing
- Add sensitive fields:
walletAddressprivateKeysecretKeymnemonic
# Add to your existing Dockerfile
ARG GIT_COMMIT_HASH=unknown
ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH}
ENV SENTRY_RELEASE=${GIT_COMMIT_HASH}# Add to your Vite build
ARG VITE_SENTRY_RELEASE
ARG VITE_GIT_COMMIT_HASH
ENV VITE_SENTRY_RELEASE=${VITE_SENTRY_RELEASE}
ENV VITE_GIT_COMMIT_HASH=${VITE_GIT_COMMIT_HASH}Ensure these are set in your production environment:
| Variable | Frontend | Backend | Required |
|---|---|---|---|
*_SENTRY_DSN |
✅ | ✅ | Yes |
*_SENTRY_ENVIRONMENT |
✅ | ✅ | Yes |
*_SENTRY_RELEASE |
✅ | ✅ | Recommended |
*_GIT_COMMIT_HASH |
✅ | ✅ | Recommended |
*_TRACES_SAMPLE_RATE |
✅ | ✅ | Optional |
# Add a test endpoint (development only)
app.get("/api/test-error", () => {
throw new Error("Test error - Sentry verification")
})
# Trigger and verify in Sentry dashboard
curl http://localhost:4000/api/test-error// Add a test button (development only)
<button onClick={() => {
throw new Error("Test error - Sentry verification")
}}>
Test Sentry
</button>- Errors appear in Sentry dashboard within 30 seconds
- Wallet addresses are redacted in error details
- Request context (path, method) is attached to backend errors
- Breadcrumbs show user actions before errors
- Release version matches deployment commit hash
- Environment is correctly labeled
- Performance traces are captured (check Transactions tab)
- Check DSN: Verify DSN is correctly set in environment variables
- Check Network: Ensure Sentry.io is accessible from your servers
- Check Filters: Verify no project filters are blocking events
- Check Quota: Ensure you haven't exceeded event quota
- Custom Data: If you manually add contexts, ensure scrubbing is applied
- Stack Traces: Some third-party frames may not be scrubbed
- Server-Side: Enable Sentry's built-in scrubbing as backup
If Sentry impacts performance:
- Reduce Sample Rates: Lower
tracesSampleRatein production - Disable Replay: Set
replaysSessionSampleRateto 0 - Check Network: Use Sentry's regional endpoints if available
If you see TypeScript errors after installation:
# Regenerate types
npm install --save-dev @types/nodeFor issues with this integration:
- Check the Sentry dashboard for error details
- Review the Sentry documentation
- Contact the platform team via Slack #sentry-support