Documentation Index Fetch the complete documentation index at: https://mintlify.com/getsentry/sentry-javascript/llms.txt
Use this file to discover all available pages before exploring further.
Proper error handling ensures you capture actionable information while avoiding noise and maintaining application stability.
Capturing Errors
Automatic Error Capture
Sentry automatically captures unhandled errors and promise rejections:
import * as Sentry from '@sentry/browser' ;
Sentry . init ({
dsn: '__DSN__' ,
integrations: [
// Enabled by default
Sentry . globalHandlersIntegration (),
],
});
// These are captured automatically:
throw new Error ( 'Uncaught error' );
Promise . reject ( new Error ( 'Unhandled rejection' ));
window . addEventListener ( 'error' , ( event ) => {
// Captured automatically
});
Manual Error Capture
Capture errors in try-catch blocks:
try {
riskyOperation ();
} catch ( error ) {
Sentry . captureException ( error );
// Optionally rethrow
throw error ;
}
Always capture errors before rethrowing them to ensure they’re sent to Sentry even if caught by another handler.
Capturing Messages
For non-error events, use captureMessage:
// Warning level
Sentry . captureMessage ( 'Something unusual happened' , 'warning' );
// Info level
Sentry . captureMessage ( 'User performed action' , 'info' );
// Error level
Sentry . captureMessage ( 'Critical system state' , 'error' );
Adding Context
User Context
Identify users to track who experiences errors:
Sentry . setUser ({
id: '12345' ,
username: 'john_doe' ,
email: 'john@example.com' ,
ip_address: '{{auto}}' , // Auto-detect IP
});
// Clear user on logout
Sentry . setUser ( null );
Be mindful of privacy regulations (GDPR, CCPA) when setting user data. Only include PII if you have user consent.
Add searchable key-value pairs:
// Set tags globally
Sentry . setTags ({
environment: 'production' ,
feature: 'checkout' ,
});
// Set a single tag
Sentry . setTag ( 'page_locale' , 'en-US' );
// Set tags for a specific error
Sentry . withScope (( scope ) => {
scope . setTag ( 'section' , 'payment' );
Sentry . captureException ( new Error ( 'Payment failed' ));
});
Add structured data to events:
Sentry . setContext ( 'character' , {
name: 'Mighty Fighter' ,
level: 42 ,
class: 'warrior' ,
});
// For a specific error
Sentry . withScope (( scope ) => {
scope . setContext ( 'order' , {
id: 'order-123' ,
items: 5 ,
total: 99.99 ,
});
Sentry . captureException ( new Error ( 'Order processing failed' ));
});
Fingerprinting
Control how errors are grouped:
Sentry . withScope (( scope ) => {
scope . setFingerprint ([ '{{ default }}' , 'custom-group' ]);
Sentry . captureException ( error );
});
// Dynamic fingerprinting based on error
try {
await apiCall ();
} catch ( error ) {
Sentry . withScope (( scope ) => {
if ( error . code === 'RATE_LIMIT' ) {
scope . setFingerprint ([ 'rate-limit' , error . endpoint ]);
} else {
scope . setFingerprint ([ '{{ default }}' ]);
}
Sentry . captureException ( error );
});
}
Breadcrumbs
Breadcrumbs provide a trail of events leading to an error:
// Manual breadcrumbs
Sentry . addBreadcrumb ({
category: 'auth' ,
message: 'User logged in' ,
level: 'info' ,
});
Sentry . addBreadcrumb ({
category: 'api' ,
message: 'Fetching user profile' ,
level: 'info' ,
data: {
url: '/api/profile' ,
method: 'GET' ,
},
});
// Automatic breadcrumbs from integrations
Sentry . init ({
dsn: '__DSN__' ,
integrations: [
Sentry . breadcrumbsIntegration ({
console: true , // Console logs
dom: true , // DOM events
fetch: true , // Fetch requests
history: true , // Navigation
sentry: true , // Sentry API calls
xhr: true , // XMLHttpRequest
}),
],
});
Scope Management
Isolation Scope
Use isolation scopes for request-level context in Node.js:
import * as Sentry from '@sentry/node' ;
app . use (( req , res , next ) => {
Sentry . withIsolationScope (( scope ) => {
scope . setTag ( 'request_id' , req . id );
scope . setUser ({ id: req . userId });
next ();
});
});
Current Scope
Modify the current scope temporarily:
// Set data on current scope
Sentry . getCurrentScope (). setTag ( 'feature' , 'new-checkout' );
// Isolate scope for a specific operation
Sentry . withScope (( scope ) => {
scope . setLevel ( 'warning' );
scope . setTag ( 'transaction_type' , 'refund' );
Sentry . captureMessage ( 'Refund processed' );
});
// Scope changes are discarded after the callback
Error Boundaries (React)
Use error boundaries to catch React component errors:
import * as Sentry from '@sentry/react' ;
function App () {
return (
< Sentry.ErrorBoundary
fallback = { < ErrorFallback /> }
showDialog
onError = { ( error , componentStack , eventId ) => {
console . log ( 'Error caught by boundary:' , error );
} }
>
< YourApp />
</ Sentry.ErrorBoundary >
);
}
function ErrorFallback ({ error , componentStack , resetError }) {
return (
< div >
< h1 > Something went wrong </ h1 >
< button onClick = { resetError } > Try again </ button >
</ div >
);
}
Customizing Error Boundaries
import { ErrorBoundary } from '@sentry/react' ;
function MyErrorBoundary ({ children }) {
return (
< ErrorBoundary
beforeCapture = { ( scope , error , errorInfo ) => {
scope . setTag ( 'error_boundary' , 'MyErrorBoundary' );
scope . setContext ( 'component_stack' , {
stack: errorInfo . componentStack ,
});
} }
onError = { ( error , componentStack , eventId ) => {
// Log to analytics
analytics . track ( 'error_boundary_caught' , {
eventId ,
error: error . message ,
});
} }
onReset = { () => {
// Reset app state
window . location . href = '/' ;
} }
fallback = { ({ error , resetError }) => (
< div >
< h2 > Oops! Something went wrong </ h2 >
< pre > { error . message } </ pre >
< button onClick = { resetError } > Reset </ button >
</ div >
) }
>
{ children }
</ ErrorBoundary >
);
}
Async Error Handling
Promises
// Unhandled rejections are caught automatically
fetch ( '/api/data' )
. then ( response => response . json ())
. then ( data => processData ( data ));
// If any step throws, Sentry captures it
// Manual capture in catch
fetch ( '/api/data' )
. then ( response => response . json ())
. catch ( error => {
Sentry . captureException ( error );
throw error ; // Rethrow if needed
});
Async/Await
async function fetchUserData ( userId ) {
try {
const response = await fetch ( `/api/users/ ${ userId } ` );
const data = await response . json ();
return data ;
} catch ( error ) {
Sentry . captureException ( error );
// Add context
Sentry . setContext ( 'api_call' , {
userId ,
endpoint: '/api/users' ,
});
throw error ;
}
}
Node.js Error Handling
Express Error Handler
import express from 'express' ;
import * as Sentry from '@sentry/node' ;
const app = express ();
// Add Sentry error handler AFTER all controllers and BEFORE other error handlers
app . use ( Sentry . setupExpressErrorHandler ( app ));
// Your error handler
app . use (( err , req , res , next ) => {
res . status ( 500 ). send ( 'Internal Server Error' );
});
Unhandled Rejections
import * as Sentry from '@sentry/node' ;
Sentry . init ({
dsn: '__DSN__' ,
integrations: [
// Enabled by default
Sentry . onUncaughtExceptionIntegration ({
onFatalError : ( error ) => {
console . error ( 'Fatal error:' , error );
process . exit ( 1 );
},
}),
Sentry . onUnhandledRejectionIntegration ({
mode: 'warn' , // 'warn' or 'strict'
}),
],
});
Enriching Error Data
Stack Traces
import * as Sentry from '@sentry/browser' ;
Sentry . init ({
dsn: '__DSN__' ,
attachStacktrace: true , // Attach stack traces to messages
});
Source Maps
Ensure source maps are uploaded for readable stack traces:
// next.config.js (Next.js)
const { withSentryConfig } = require ( '@sentry/nextjs' );
module . exports = withSentryConfig (
{
// Next.js config
},
{
// Sentry webpack plugin config
silent: true ,
org: 'your-org' ,
project: 'your-project' ,
}
);
Context Lines Integration
import { contextLinesIntegration } from '@sentry/browser' ;
Sentry . init ({
dsn: '__DSN__' ,
integrations: [
contextLinesIntegration (), // Shows source code around error
],
});
Handling Specific Error Types
Network Errors
async function fetchWithErrorHandling ( url ) {
try {
const response = await fetch ( url );
if ( ! response . ok ) {
const error = new Error ( `HTTP ${ response . status } ` );
Sentry . withScope (( scope ) => {
scope . setTag ( 'http_status' , response . status );
scope . setContext ( 'request' , {
url ,
method: 'GET' ,
status: response . status ,
});
Sentry . captureException ( error );
});
throw error ;
}
return response . json ();
} catch ( error ) {
if ( error . name === 'TypeError' ) {
// Network error
Sentry . withScope (( scope ) => {
scope . setTag ( 'error_type' , 'network' );
scope . setLevel ( 'warning' );
Sentry . captureException ( error );
});
}
throw error ;
}
}
Validation Errors
function validateUserInput ( data ) {
const errors = [];
if ( ! data . email ) {
errors . push ( 'Email required' );
}
if ( errors . length > 0 ) {
const error = new Error ( 'Validation failed' );
Sentry . withScope (( scope ) => {
scope . setLevel ( 'info' ); // Validation errors aren't critical
scope . setContext ( 'validation' , {
errors ,
data: { ... data , password: '[Filtered]' },
});
Sentry . captureException ( error );
});
throw error ;
}
}
Best Practices
Always add context before capturing
Context helps debug issues faster: // ❌ Bad
Sentry . captureException ( error );
// ✅ Good
Sentry . withScope (( scope ) => {
scope . setTag ( 'feature' , 'checkout' );
scope . setContext ( 'cart' , { items: 3 , total: 99.99 });
Sentry . captureException ( error );
});
Use error levels appropriately
Set appropriate severity levels: // Fatal: app crashes
scope . setLevel ( 'fatal' );
// Error: exceptions
scope . setLevel ( 'error' );
// Warning: deprecated API usage
scope . setLevel ( 'warning' );
// Info: user actions
scope . setLevel ( 'info' );
// Debug: detailed logging
scope . setLevel ( 'debug' );
Don't swallow errors silently
Always log or capture errors: // ❌ Bad
try {
riskyOperation ();
} catch ( error ) {
// Silent failure
}
// ✅ Good
try {
riskyOperation ();
} catch ( error ) {
Sentry . captureException ( error );
// Handle gracefully
showErrorMessage ();
}
Use custom fingerprints for known errors
Group related errors together: try {
await paymentGateway . process ();
} catch ( error ) {
Sentry . withScope (( scope ) => {
if ( error . code === 'INSUFFICIENT_FUNDS' ) {
scope . setFingerprint ([ 'payment' , 'insufficient-funds' ]);
}
Sentry . captureException ( error );
});
}
Monitor error rates, not just errors
Use Sentry’s alerts to monitor error rate increases, which can indicate new issues.
Complete Example
import * as Sentry from '@sentry/browser' ;
Sentry . init ({
dsn: '__DSN__' ,
environment: 'production' ,
attachStacktrace: true ,
integrations: [
Sentry . breadcrumbsIntegration (),
Sentry . globalHandlersIntegration (),
Sentry . contextLinesIntegration (),
],
beforeSend ( event , hint ) {
// Filter out sensitive data
if ( event . request ?. headers ) {
delete event . request . headers [ 'Authorization' ];
}
return event ;
},
});
// Set user context
function setUserContext ( user ) {
Sentry . setUser ({
id: user . id ,
username: user . username ,
email: user . email ,
});
}
// API call with error handling
async function apiCall ( endpoint , options = {}) {
try {
const response = await fetch ( endpoint , options );
if ( ! response . ok ) {
throw new Error ( `HTTP ${ response . status } : ${ response . statusText } ` );
}
return await response . json ();
} catch ( error ) {
Sentry . withScope (( scope ) => {
scope . setTag ( 'api_endpoint' , endpoint );
scope . setContext ( 'request' , {
endpoint ,
method: options . method || 'GET' ,
status: error . status ,
});
if ( error . status >= 500 ) {
scope . setLevel ( 'error' );
} else if ( error . status >= 400 ) {
scope . setLevel ( 'warning' );
}
Sentry . captureException ( error );
});
throw error ;
}
}
export { apiCall , setUserContext };
Next Steps
Performance Monitoring Monitor application performance
Source Maps Configure source maps for readable errors