The vij-sdk provides two main APIs for capturing errors and messages: captureException() for error objects and captureMessage() for custom log messages.
captureException()
Capture and send error objects to your VIJ Admin dashboard.
Basic Usage
import { captureException } from "vij-sdk" ;
try {
// Code that might throw an error
const result = riskyOperation ();
} catch ( error ) {
captureException ( error );
}
Signature
captureException (
error : Error ,
metadata ?: Record < string , any > ,
severity ?: "error" | "warning" | "info"
): void
Parameters
The error object to capture. Can be any JavaScript Error instance or object with name, message, and stack properties. Supported Types :
Native JavaScript errors (Error, TypeError, ReferenceError, etc.)
Custom error classes extending Error
Objects with error-like structure
// Native error
captureException ( new Error ( "Something went wrong" ));
// Custom error class
class ValidationError extends Error {
constructor ( message ) {
super ( message );
this . name = "ValidationError" ;
}
}
captureException ( new ValidationError ( "Invalid email format" ));
// Error from catch block
try {
await fetchData ();
} catch ( error ) {
captureException ( error );
}
Additional contextual information to attach to this specific error. Use Cases :
User information (ID, email, role)
Request details (URL, method, headers)
Application state at time of error
Feature or component context
captureException ( error , {
userId: "user-123" ,
userEmail: "user@example.com" ,
feature: "checkout" ,
cartTotal: 99.99 ,
requestUrl: "/api/payment" ,
requestMethod: "POST"
});
Metadata is merged with global metadata from init(). Per-error metadata takes precedence.
The severity level of this error. Options :
"error" - Critical errors requiring immediate attention
"warning" - Non-critical issues that should be investigated
"info" - Informational logs for tracking behavior
// Critical error
captureException ( error , { feature: "payment" }, "error" );
// Non-critical warning
captureException ( deprecationError , { api: "legacy" }, "warning" );
// Informational
captureException ( new Error ( "Rate limit approaching" ), {}, "info" );
Severity levels help you filter and prioritize errors in the dashboard.
Automatic Error Capture
The SDK automatically captures uncaught errors and unhandled promise rejections without any additional code:
// Automatically captured - no try/catch needed
window . addEventListener ( "click" , () => {
throw new Error ( "Button click error" ); // Captured automatically
});
// Unhandled promise rejection - automatically captured
fetch ( "/api/data" ). then ( response => {
throw new Error ( "Processing failed" ); // Captured automatically
});
Browser Events Captured :
window.onerror - Uncaught exceptions
window.onunhandledrejection - Unhandled promise rejections
// Automatically captured - no try/catch needed
process . nextTick (() => {
throw new Error ( "Async error" ); // Captured automatically
});
// Unhandled promise rejection - automatically captured
Promise . reject ( new Error ( "Rejected promise" )); // Captured automatically
Node.js Events Captured :
process.on("uncaughtException") - Uncaught exceptions
process.on("unhandledRejection") - Unhandled promise rejections
While automatic capture is convenient, it’s better to explicitly catch and handle errors in production code. Use captureException() in catch blocks for better control.
Advanced Examples
import { captureException } from "vij-sdk" ;
async function processPayment ( userId , amount ) {
try {
const payment = await stripeAPI . charge ({ userId , amount });
return payment ;
} catch ( error ) {
captureException ( error , {
// User context
userId: userId ,
userPlan: "premium" ,
// Transaction context
paymentAmount: amount ,
currency: "USD" ,
// Application state
cartItems: 5 ,
discountApplied: true ,
// Technical details
stripeApiVersion: "2023-10-16" ,
timestamp: new Date (). toISOString ()
});
throw error ; // Re-throw after capturing
}
}
Capturing Errors in React Components
import { captureException } from "vij-sdk" ;
import { Component } from "react" ;
class ErrorBoundary extends Component {
componentDidCatch ( error , errorInfo ) {
captureException ( error , {
componentStack: errorInfo . componentStack ,
route: window . location . pathname ,
userAgent: navigator . userAgent
});
}
render () {
return this . props . children ;
}
}
Capturing Errors in Express Middleware
import { captureException } from "vij-sdk" ;
app . use (( err , req , res , next ) => {
captureException ( err , {
requestUrl: req . originalUrl ,
requestMethod: req . method ,
requestHeaders: req . headers ,
requestBody: req . body ,
userId: req . user ?. id ,
ipAddress: req . ip
});
res . status ( 500 ). json ({ error: "Internal server error" });
});
captureMessage()
Capture custom log messages without an error object.
Basic Usage
import { captureMessage } from "vij-sdk" ;
captureMessage ( "User logged in successfully" );
Signature
captureMessage (
message : string ,
metadata ?: Record < string , any > ,
severity ?: "error" | "warning" | "info"
): void
Parameters
The log message to capture. Best Practices :
Use clear, descriptive messages
Include relevant details in the message or metadata
Keep messages concise but informative
// Good
captureMessage ( "Payment processed successfully for order #12345" );
// Better - use metadata
captureMessage ( "Payment processed successfully" , { orderId: 12345 });
Additional contextual information to attach to this message. captureMessage ( "User action" , {
action: "button_click" ,
buttonId: "checkout" ,
userId: "user-123" ,
timestamp: Date . now ()
});
The severity level of this message. Options :
"info" - Informational messages (default for captureMessage)
"warning" - Warning messages
"error" - Error messages
// Info level (default)
captureMessage ( "User logged in" , { userId: "123" }, "info" );
// Warning level
captureMessage ( "Rate limit approaching" , { requestCount: 950 }, "warning" );
// Error level
captureMessage ( "Configuration missing" , { key: "API_KEY" }, "error" );
Use Cases
User Actions
System Events
Performance Monitoring
Business Logic
import { captureMessage } from "vij-sdk" ;
function trackUserAction ( action , details ) {
captureMessage ( `User action: ${ action } ` , {
userId: details . userId ,
actionType: action ,
timestamp: new Date (). toISOString (),
... details
}, "info" );
}
// Track button clicks
trackUserAction ( "checkout_clicked" , {
userId: "user-123" ,
cartValue: 99.99
});
// Track form submissions
trackUserAction ( "form_submitted" , {
formId: "contact-form" ,
fields: 5
});
import { captureMessage } from "vij-sdk" ;
// Database connection
captureMessage ( "Database connected successfully" , {
host: "mongodb.example.com" ,
database: "production" ,
connectTime: 1234
}, "info" );
// Cache operations
captureMessage ( "Cache hit" , {
key: "user:123" ,
ttl: 3600
}, "info" );
// Scheduled tasks
captureMessage ( "Cron job completed" , {
job: "daily-report" ,
duration: 5432 ,
recordsProcessed: 10000
}, "info" );
import { captureMessage } from "vij-sdk" ;
function trackPerformance ( operation , duration ) {
const severity = duration > 5000 ? "warning" : "info" ;
captureMessage ( `Performance: ${ operation } ` , {
operation ,
duration ,
threshold: 5000 ,
exceeded: duration > 5000
}, severity );
}
// Track API response times
const start = Date . now ();
await fetchData ();
trackPerformance ( "fetchData" , Date . now () - start );
import { captureMessage } from "vij-sdk" ;
// Track important business events
captureMessage ( "Order placed" , {
orderId: "ORD-12345" ,
userId: "user-123" ,
total: 199.99 ,
items: 3 ,
paymentMethod: "credit_card"
}, "info" );
// Track threshold events
if ( inventoryCount < 10 ) {
captureMessage ( "Low inventory warning" , {
productId: "PROD-456" ,
currentStock: inventoryCount ,
threshold: 10
}, "warning" );
}
Contextual Information
Both captureException() and captureMessage() automatically collect rich contextual information:
Browser Context
{
"viewport" : {
"width" : 1920 ,
"height" : 1080
},
"screen" : {
"width" : 1920 ,
"height" : 1080 ,
"colorDepth" : 24
},
"browser" : {
"userAgent" : "Mozilla/5.0..." ,
"language" : "en-US" ,
"platform" : "MacIntel" ,
"cookieEnabled" : true ,
"doNotTrack" : "1"
},
"network" : {
"effectiveType" : "4g" ,
"downlink" : 10 ,
"rtt" : 50
}
}
Node.js Context
{
"process" : {
"pid" : 12345 ,
"platform" : "linux" ,
"arch" : "x64" ,
"nodeVersion" : "v20.0.0" ,
"uptime" : 3600 ,
"memory" : {
"rss" : 50000000 ,
"heapTotal" : 30000000 ,
"heapUsed" : 20000000 ,
"external" : 1000000
}
}
}
This context is collected automatically. You don’t need to add it manually.
Best Practices
Always include relevant metadata
Use appropriate severity levels
Error : Critical issues requiring immediate attentioncaptureException ( paymentError , { orderId: 123 }, "error" );
Warning : Issues that should be investigated but aren’t criticalcaptureException ( deprecatedApiWarning , {}, "warning" );
Info : Tracking and informational purposescaptureMessage ( "Feature flag enabled" , { flag: "new-ui" }, "info" );
Avoid capturing sensitive data
Never log passwords, tokens, or PII without sanitization: // Bad
captureException ( error , {
password: user . password , // Never log passwords!
creditCard: user . card // Never log card numbers!
});
// Good
captureException ( error , {
userId: user . id , // Use IDs instead
hasPaymentMethod: !! user . card // Use boolean flags
});
Don't capture errors in tight loops
Avoid overwhelming your VIJ instance with duplicate errors: // Bad
for ( let i = 0 ; i < 10000 ; i ++ ) {
try {
processItem ( i );
} catch ( error ) {
captureException ( error ); // Will create 10000 errors!
}
}
// Good - batch errors or add deduplication
const errors = [];
for ( let i = 0 ; i < 10000 ; i ++ ) {
try {
processItem ( i );
} catch ( error ) {
errors . push ({ index: i , error });
}
}
if ( errors . length > 0 ) {
captureException ( new Error ( `Batch processing failed` ), {
failedCount: errors . length ,
totalItems: 10000
});
}
Re-throw errors after capturing
Capture the error but don’t swallow it: // Good
try {
await criticalOperation ();
} catch ( error ) {
captureException ( error , { operation: "critical" });
throw error ; // Re-throw for upstream handling
}
// Bad
try {
await criticalOperation ();
} catch ( error ) {
captureException ( error );
// Swallowed! Upstream code won't know about the error
}
Integration Patterns
React Error Boundary
import { Component } from "react" ;
import { captureException } from "vij-sdk" ;
class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError ( error ) {
return { hasError: true };
}
componentDidCatch ( error , errorInfo ) {
captureException ( error , {
componentStack: errorInfo . componentStack ,
route: window . location . pathname
});
}
render () {
if ( this . state . hasError ) {
return < h1 > Something went wrong. </ h1 > ;
}
return this . props . children ;
}
}
Vue Error Handler
import { createApp } from "vue" ;
import { captureException } from "vij-sdk" ;
const app = createApp ( App );
app . config . errorHandler = ( err , instance , info ) => {
captureException ( err , {
componentName: instance ?. $options ?. name ,
errorInfo: info ,
route: window . location . pathname
});
};
app . mount ( "#app" );
Express Error Middleware
import express from "express" ;
import { captureException } from "vij-sdk" ;
const app = express ();
// Routes...
// Error handling middleware (must be last)
app . use (( err , req , res , next ) => {
captureException ( err , {
url: req . originalUrl ,
method: req . method ,
headers: req . headers ,
body: req . body ,
params: req . params ,
query: req . query ,
userId: req . user ?. id
});
res . status ( 500 ). json ({ error: "Internal server error" });
});
Async/Await Error Handling
import { captureException } from "vij-sdk" ;
async function fetchUserData ( userId ) {
try {
const response = await fetch ( `/api/users/ ${ userId } ` );
if ( ! response . ok ) {
throw new Error ( `HTTP ${ response . status } : ${ response . statusText } ` );
}
return await response . json ();
} catch ( error ) {
captureException ( error , {
operation: "fetchUserData" ,
userId ,
timestamp: new Date (). toISOString ()
});
throw error ;
}
}
Troubleshooting
Errors not appearing in dashboard
Check the following :
Verify init() was called before captureException()
Check browser console/server logs for network errors
Ensure VIJ Admin endpoint is accessible
Verify batching settings aren’t delaying delivery too long
Check that error object has name, message, and stack properties
Debug : Disable batching for immediate deliveryinit ({ batch: false , /* ... */ });
Duplicate errors appearing
Cause : Same error being captured multiple timesSolutions :
Check if error is being captured in both automatic handlers and manual try/catch
Implement deduplication logic for recurring errors
Use error grouping features in VIJ Admin dashboard
Learn more about error grouping →
Next Steps
SDK Configuration Learn about all available SDK configuration options
API Reference Explore the complete SDK API documentation
Error Grouping Understand how VIJ groups similar errors
Dashboard Features Explore VIJ Admin dashboard features