@hunghoangdev123/sentry-sdk
v1.0.0
Published
A comprehensive Sentry SDK wrapper with full configuration options support via DSN and environment variables
Maintainers
Readme
@hunghoang/sentry-sdk
🚀 A comprehensive Sentry SDK wrapper for Node.js with full configuration support via DSN and environment variables.
✨ Features
- 🔧 Full Configuration Support: All Sentry options available through code or environment variables
- 🌍 Environment Variable Support: Configure everything via
.envfile - 📝 TypeScript Support: Full type definitions included
- 🎯 Easy to Use: Simple initialization with sensible defaults
- 🔒 Production Ready: Battle-tested configuration patterns
- 📦 Lightweight: Minimal dependencies
- 🎨 Flexible: Override any option programmatically
📦 Installation
npm install @hunghoang/sentry-sdk @sentry/nodeOr with yarn:
yarn add @hunghoang/sentry-sdk @sentry/node✅ Compatibility
- ✅ Node.js >= 12.0.0 (tested on v20.18.3)
- ✅ JavaScript (no TypeScript required)
- ✅ CommonJS (
require) - ✅ ES Modules (
import) - ✅ TypeScript (full type definitions included)
See COMPATIBILITY.md for detailed JavaScript usage examples.
🚀 Quick Start
Basic Usage
import { initSentry } from '@hunghoang/sentry-sdk';
// Initialize with DSN from environment variable SENTRY_DSN
initSentry();With Custom Options
import { initSentry } from '@hunghoang/sentry-sdk';
initSentry({
dsn: 'https://[email protected]/0',
environment: 'production',
release: '[email protected]',
tracesSampleRate: 1.0,
debug: false,
});Express.js Example
import express from 'express';
import { initSentry, Sentry } from '@hunghoang/sentry-sdk';
const app = express();
// Initialize Sentry before any routes
initSentry({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
});
// Request handler must be the first middleware
app.use(Sentry.Handlers.requestHandler());
// Tracing handler for performance monitoring
app.use(Sentry.Handlers.tracingHandler());
// Your routes
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Error handler must be before any other error middleware and after all controllers
app.use(Sentry.Handlers.errorHandler());
app.listen(3000);🔐 Environment Variables
Create a .env file in your project root:
# Required
SENTRY_DSN=https://[email protected]/0
# Optional
SENTRY_ENVIRONMENT=production
[email protected]
SENTRY_DEBUG=false
# Sampling
SENTRY_SAMPLE_RATE=1.0
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0.1
# Breadcrumbs
SENTRY_MAX_BREADCRUMBS=100
SENTRY_MAX_VALUE_LENGTH=250
# Features
SENTRY_ATTACH_STACKTRACE=true
SENTRY_SEND_DEFAULT_PII=false
SENTRY_AUTO_SESSION_TRACKING=true
SENTRY_ENABLE_TRACING=true
# Server
SENTRY_SERVER_NAME=my-server
SENTRY_MAX_QUEUE_SIZE=30
SENTRY_SHUTDOWN_TIMEOUT=2000
# Filtering (comma-separated)
SENTRY_IGNORE_ERRORS=NetworkError,TimeoutError
SENTRY_IGNORE_TRANSACTIONS=/health,/ping
SENTRY_DENY_URLS=localhost,127.0.0.1
SENTRY_ALLOW_URLS=myapp.com,api.myapp.com
# Distribution
SENTRY_DIST=build-123📖 Configuration Options
Core Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| dsn | string | - | The DSN tells the SDK where to send events |
| environment | string | NODE_ENV | Environment name (production, staging, etc.) |
| release | string | - | Release version of your application |
| debug | boolean | false | Enable debug mode for troubleshooting |
Sampling Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| sampleRate | number | 1.0 | Sample rate for error events (0.0 to 1.0) |
| tracesSampleRate | number | - | Sample rate for performance monitoring (0.0 to 1.0) |
| profilesSampleRate | number | - | Sample rate for profiling (0.0 to 1.0) |
Breadcrumbs Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| maxBreadcrumbs | number | 100 | Maximum number of breadcrumbs |
| maxValueLength | number | 250 | Maximum length of breadcrumb values |
Feature Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| attachStacktrace | boolean | true | Attach stack traces to messages |
| sendDefaultPii | boolean | false | Send personally identifiable information |
| autoSessionTracking | boolean | true | Automatically track sessions |
| enableTracing | boolean | - | Enable performance monitoring |
Filtering Options
| Option | Type | Description |
|--------|------|-------------|
| ignoreErrors | Array<string \| RegExp> | Error messages to ignore |
| ignoreTransactions | Array<string \| RegExp> | Transaction names to ignore |
| denyUrls | Array<string \| RegExp> | URLs to exclude from tracking |
| allowUrls | Array<string \| RegExp> | URLs to include in tracking |
🎯 API Reference
initSentry(options?: SentrySDKOptions): SentrySDKResult
Initialize the Sentry SDK with the provided options. Options passed directly will override environment variables.
const result = initSentry({
dsn: 'https://...',
environment: 'production',
});
console.log(result.initialized); // truecloseSentry(timeout?: number): Promise<boolean>
Close the Sentry SDK and flush pending events.
await closeSentry(5000); // Wait up to 5 secondsflushSentry(timeout?: number): Promise<boolean>
Flush pending events without closing the SDK.
await flushSentry(2000);captureException(exception: any, context?: any): string
Capture an exception.
try {
throw new Error('Something went wrong');
} catch (error) {
captureException(error, {
tags: { section: 'checkout' },
extra: { orderId: '12345' },
});
}captureMessage(message: string, level?: string): string
Capture a message.
captureMessage('Payment processed successfully', 'info');addBreadcrumb(breadcrumb: Breadcrumb): void
Add a breadcrumb for better error context.
addBreadcrumb({
category: 'auth',
message: 'User logged in',
level: 'info',
data: {
userId: '123',
username: 'john_doe',
},
});setUser(user: User | null): void
Set user information.
setUser({
id: '123',
email: '[email protected]',
username: 'john_doe',
ip_address: '{{auto}}',
});
// Clear user
setUser(null);setTag(key: string, value: string): void
Set a single tag.
setTag('page_locale', 'en-US');setTags(tags: object): void
Set multiple tags.
setTags({
page_locale: 'en-US',
user_type: 'premium',
feature_flag: 'new_ui',
});setExtra(key: string, value: any): void
Set extra context data.
setExtra('shopping_cart', {
items: 3,
total: 99.99,
});setContext(name: string, context: object | null): void
Set custom context.
setContext('character', {
name: 'John Doe',
age: 30,
occupation: 'Developer',
});configureScope(callback: (scope: Scope) => void): void
Configure the current scope.
configureScope((scope) => {
scope.setTag('section', 'admin');
scope.setLevel('warning');
scope.setFingerprint(['custom-fingerprint']);
});startTransaction(context: any): Transaction
Start a performance monitoring transaction.
const transaction = startTransaction({
name: 'process-order',
op: 'task',
});
try {
// Your code here
const span = transaction.startChild({
op: 'db',
description: 'Fetch user data',
});
// Do database work
span.finish();
} finally {
transaction.finish();
}withErrorHandling<T>(fn: T): T
Wrap a function with automatic error handling.
const processOrder = withErrorHandling(async (orderId: string) => {
// Your code here
// Any errors will be automatically captured by Sentry
});
await processOrder('12345');🔥 Advanced Usage
Custom Error Filtering
initSentry({
dsn: process.env.SENTRY_DSN,
beforeSend(event, hint) {
// Don't send events with specific error messages
if (event.exception) {
const error = hint.originalException;
if (error && error.message?.includes('User cancelled')) {
return null; // Don't send to Sentry
}
}
// Remove sensitive data
if (event.request?.data) {
delete event.request.data.password;
delete event.request.data.creditCard;
}
return event;
},
});Custom Breadcrumbs
initSentry({
dsn: process.env.SENTRY_DSN,
beforeBreadcrumb(breadcrumb, hint) {
// Filter out breadcrumbs with sensitive data
if (breadcrumb.category === 'console') {
return null;
}
// Modify breadcrumbs
if (breadcrumb.category === 'fetch') {
breadcrumb.data = {
...breadcrumb.data,
timestamp: Date.now(),
};
}
return breadcrumb;
},
});Performance Monitoring
import { initSentry, startTransaction } from '@hunghoang/sentry-sdk';
initSentry({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.2, // Sample 20% of transactions
enableTracing: true,
});
async function processData() {
const transaction = startTransaction({
name: 'process-data',
op: 'task',
});
try {
// Database query
const dbSpan = transaction.startChild({
op: 'db',
description: 'SELECT * FROM users',
});
await db.query('SELECT * FROM users');
dbSpan.finish();
// HTTP request
const httpSpan = transaction.startChild({
op: 'http.client',
description: 'GET https://api.example.com/data',
});
await fetch('https://api.example.com/data');
httpSpan.finish();
transaction.setStatus('ok');
} catch (error) {
transaction.setStatus('internal_error');
throw error;
} finally {
transaction.finish();
}
}Context and Scope Management
import { configureScope, setUser, setTag } from '@hunghoang/sentry-sdk';
// Set global context that applies to all events
setUser({
id: '12345',
email: '[email protected]',
});
setTag('server', 'us-east-1');
// Use local scope for specific operations
import { Sentry } from '@hunghoang/sentry-sdk';
Sentry.withScope((scope) => {
scope.setTag('section', 'payment');
scope.setLevel('warning');
Sentry.captureMessage('Payment processing started');
});🧪 Testing
When testing your application, you might want to disable Sentry:
// In your test setup
process.env.SENTRY_DSN = '';
// Or
initSentry({
dsn: process.env.NODE_ENV === 'test' ? '' : process.env.SENTRY_DSN,
});📝 Best Practices
- Always set environment and release: This helps you track errors across different deployments
initSentry({
environment: process.env.NODE_ENV,
release: `my-app@${process.env.npm_package_version}`,
});- Use appropriate sample rates: Don't send 100% of transactions in production
initSentry({
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
});- Filter sensitive data: Use
beforeSendto remove PII
initSentry({
beforeSend(event) {
// Remove sensitive data
if (event.request) {
delete event.request.cookies;
}
return event;
},
});- Add context to errors: Use breadcrumbs, tags, and extra data
addBreadcrumb({
category: 'user-action',
message: 'User clicked checkout button',
level: 'info',
});
try {
await processPayment();
} catch (error) {
captureException(error, {
tags: { payment_method: 'credit_card' },
extra: { amount: 99.99 },
});
}- Close Sentry gracefully: Flush events before shutdown
process.on('SIGTERM', async () => {
await closeSentry(5000);
process.exit(0);
});🔧 Troubleshooting
Events not appearing in Sentry
- Check that your DSN is correct
- Enable debug mode:
SENTRY_DEBUG=true - Check network connectivity
- Verify sample rates are not filtering out events
High event volume
- Reduce sample rates
- Use
ignoreErrorsto filter common errors - Implement rate limiting with
beforeSend
Missing context
- Ensure breadcrumbs are enabled
- Check that context is set before errors occur
- Verify
attachStacktraceis enabled
📄 License
MIT
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📞 Support
For issues and questions:
- Create an issue on GitHub
- Check Sentry documentation: https://docs.sentry.io/
🔗 Links
Made with ❤️ by Hung Hoang
