Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AslamSDM/mentiq-sdk/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Error tracking automatically captures JavaScript errors, unhandled promise rejections, and React component errors. This helps you identify and fix issues quickly, improving application stability and user experience.
Quick Start
Enable Error Tracking
Set enableErrorTracking: true in your analytics configuration:import { AnalyticsProvider } from "mentiq-sdk";
function App() {
return (
<AnalyticsProvider
config={{
apiKey: "your-api-key",
projectId: "your-project-id",
enableErrorTracking: true,
}}
>
<YourApp />
</AnalyticsProvider>
);
}
Automatic Error Capture
Once enabled, the SDK automatically captures:
- JavaScript runtime errors
- Unhandled promise rejections
- React component errors (when using ErrorBoundary)
- Network errors (optional)
View in Dashboard
Access error reports in your MentiQ dashboard to:
- See error frequency and trends
- View stack traces and context
- Identify affected users
- Track error resolution
Automatic Error Tracking
When enabled, the SDK automatically captures errors:
JavaScript Errors
From src/analytics.ts:321-365, the SDK listens for global error events:
private setupErrorTracking(): void {
if (typeof window === "undefined") return;
const trackJavaScriptError = (event: ErrorEvent) => {
const errorData: ErrorData = {
message: event.message,
stack: event.error?.stack,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
type: "javascript",
};
const analyticsEvent = createEvent("error", "javascript_error", {
error: errorData,
});
this.enqueueEvent(analyticsEvent);
};
const trackUnhandledRejection = (event: PromiseRejectionEvent) => {
const errorData: ErrorData = {
message: event.reason?.message || String(event.reason),
stack: event.reason?.stack,
type: "unhandledrejection",
};
const analyticsEvent = createEvent("error", "unhandled_rejection", {
error: errorData,
});
this.enqueueEvent(analyticsEvent);
};
window.addEventListener("error", trackJavaScriptError);
window.addEventListener("unhandledrejection", trackUnhandledRejection);
}
Error Data Structure
interface ErrorData {
message: string; // Error message
stack?: string; // Stack trace
filename?: string; // File where error occurred
lineno?: number; // Line number
colno?: number; // Column number
type: "javascript" | "unhandledrejection" | "network" | "custom";
}
Manual Error Tracking
Using the Hook
import { useErrorTracking } from "mentiq-sdk";
function MyComponent() {
const { trackJavaScriptError, trackCustomError } = useErrorTracking();
const handleOperation = async () => {
try {
await riskyOperation();
} catch (error) {
trackJavaScriptError(error, {
context: "user-operation",
userId: currentUser.id,
});
}
};
const handleValidation = () => {
if (!isValid) {
trackCustomError("Validation failed", {
field: "email",
value: email,
});
}
};
return (
<button onClick={handleOperation}>Perform Operation</button>
);
}
Using Analytics Instance
import { useAnalytics } from "mentiq-sdk";
function DataFetcher() {
const { trackCustomError } = useAnalytics();
useEffect(() => {
fetchData()
.catch(error => {
trackCustomError(error, {
context: "data-fetch",
endpoint: "/api/users",
timestamp: new Date().toISOString(),
});
});
}, []);
return <div>Loading...</div>;
}
React Error Boundaries
Use the AnalyticsErrorBoundary component to catch React component errors:
import { AnalyticsErrorBoundary } from "mentiq-sdk";
function App() {
return (
<AnalyticsErrorBoundary
fallback={<ErrorFallback />}
>
<YourApp />
</AnalyticsErrorBoundary>
);
}
function ErrorFallback() {
return (
<div>
<h1>Something went wrong</h1>
<p>We've been notified and are working on a fix.</p>
</div>
);
}
Granular Error Boundaries
Wrap specific components for better error isolation:
function Dashboard() {
return (
<div>
<AnalyticsErrorBoundary fallback={<WidgetError />}>
<CriticalWidget />
</AnalyticsErrorBoundary>
<AnalyticsErrorBoundary fallback={<ChartError />}>
<AnalyticsChart />
</AnalyticsErrorBoundary>
</div>
);
}
Use Cases
Track API Errors
function useAPI() {
const { trackCustomError } = useAnalytics();
const fetchData = async (endpoint: string) => {
try {
const response = await fetch(endpoint);
if (!response.ok) {
trackCustomError(`API Error: ${response.status}`, {
endpoint,
status: response.status,
statusText: response.statusText,
});
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
trackCustomError(error, {
context: "api-fetch",
endpoint,
});
throw error;
}
};
return { fetchData };
}
function ContactForm() {
const { trackCustomError } = useAnalytics();
const handleSubmit = (data: FormData) => {
const errors = validateForm(data);
if (errors.length > 0) {
trackCustomError("Form validation failed", {
formName: "contact-form",
errors: errors.map(e => e.field).join(", "),
errorCount: errors.length,
});
setFormErrors(errors);
return;
}
submitForm(data);
};
return <form onSubmit={handleSubmit}>...</form>;
}
Track Authentication Errors
function LoginPage() {
const { trackCustomError } = useAnalytics();
const handleLogin = async (email: string, password: string) => {
try {
await signIn(email, password);
} catch (error) {
trackCustomError(error, {
context: "authentication",
action: "login",
email_domain: email.split("@")[1], // Don't log full email
});
setError("Invalid credentials");
}
};
return <LoginForm onSubmit={handleLogin} />;
}
Track Third-Party Integration Errors
function StripeCheckout() {
const { trackCustomError } = useAnalytics();
const handlePayment = async (paymentMethod: string) => {
try {
const result = await stripe.confirmPayment(paymentMethod);
if (result.error) {
trackCustomError("Stripe payment failed", {
errorCode: result.error.code,
errorType: result.error.type,
amount: paymentAmount,
});
}
} catch (error) {
trackCustomError(error, {
context: "stripe-integration",
paymentMethod,
});
}
};
return <PaymentForm onSubmit={handlePayment} />;
}
Error Context & Enrichment
Add contextual information to errors for better debugging:
function ProductPage({ productId }) {
const { trackCustomError } = useAnalytics();
const { user } = useAuth();
const handleAddToCart = async () => {
try {
await addToCart(productId);
} catch (error) {
trackCustomError(error, {
// Context about the operation
context: "add-to-cart",
// Product info
productId,
// User info (avoid PII)
userId: user?.id,
userPlan: user?.plan,
// Device/browser info (automatically captured)
timestamp: new Date().toISOString(),
// Custom metadata
cartItemCount: cart.items.length,
});
}
};
return <AddToCartButton onClick={handleAddToCart} />;
}
Error Sampling
For high-volume applications, sample errors to reduce noise:
function useSmartErrorTracking() {
const { trackCustomError } = useAnalytics();
const trackError = (error: Error, properties?: EventProperties) => {
// Sample 10% of common errors, track all critical errors
const isCritical = properties?.severity === "critical";
const shouldTrack = isCritical || Math.random() < 0.1;
if (shouldTrack) {
trackCustomError(error, properties);
}
};
return { trackError };
}
Error Grouping
Group similar errors for better insights:
function trackGroupedError(error: Error, group: string) {
const { trackCustomError } = useAnalytics();
trackCustomError(error, {
errorGroup: group, // Group related errors
errorHash: hashError(error), // Unique identifier for deduplication
});
}
// Usage
try {
await fetchUserData();
} catch (error) {
trackGroupedError(error, "data-loading-errors");
}
Privacy Considerations
Be careful not to log sensitive information in error messages:
- Avoid logging passwords, tokens, or API keys
- Redact PII (personally identifiable information)
- Sanitize user input before logging
- Don’t log full credit card numbers
Safe Error Logging
function safeErrorTracking(error: Error, context: any) {
const { trackCustomError } = useAnalytics();
// Sanitize context to remove sensitive data
const sanitizedContext = {
...context,
password: undefined,
token: undefined,
creditCard: context.creditCard ?
`****${context.creditCard.slice(-4)}` : undefined,
email: context.email ?
context.email.split("@")[1] : undefined, // Only log domain
};
trackCustomError(error, sanitizedContext);
}
Error Hook API
From src/hooks.ts:117-172, the useErrorTracking hook provides:
const {
trackJavaScriptError,
trackCustomError
} = useErrorTracking();
// Track JavaScript Error objects
trackJavaScriptError(error: Error, properties?: EventProperties)
// Track custom error messages
trackCustomError(message: string, properties?: EventProperties)
The hook also auto-tracks global errors:
useEffect(() => {
const handleError = (event: ErrorEvent) => {
trackJavaScriptError(event.error, {
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
});
};
const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
trackCustomError(`Unhandled Promise Rejection: ${event.reason}`, {
type: "unhandledrejection",
});
};
window.addEventListener("error", handleError);
window.addEventListener("unhandledrejection", handleUnhandledRejection);
return () => {
window.removeEventListener("error", handleError);
window.removeEventListener("unhandledrejection", handleUnhandledRejection);
};
}, []);
Best Practices
Error Tracking Tips:
- Always include context (what the user was doing)
- Add user and session identifiers for debugging
- Group related errors for better insights
- Set severity levels (critical, warning, info)
- Don’t log sensitive user data
- Sample high-frequency errors to avoid noise
- Monitor error trends, not just counts
Troubleshooting
Errors Not Being Captured
- Verify
enableErrorTracking: true in config
- Check browser console for SDK errors (enable
debug: true)
- Ensure error occurs after SDK initialization
Missing Stack Traces
Stack traces may be missing for:
- Cross-origin errors (CORS)
- Minified code without source maps
- Some browser privacy settings
Enable source maps in production for better stack traces.
Duplicate Errors
If seeing duplicate errors:
- Check for multiple error listeners
- Ensure only one AnalyticsProvider exists
- Verify error boundary isn’t re-mounting