Cognition: Error Capture
How Cognition catches errors automatically and manually, builds breadcrumb trails, parses V8 stack frames, and enriches events with user context and severity levels.
Cognition catches errors two ways: automatically, through global process handlers installed at startup, and manually, through captureError() and captureMessage(). Either way, every event arrives at Skytells with the full stack trace, a breadcrumb history, user context, tags, and runtime metadata already attached.
Automatic Error Capture
When captureErrors: true (the default), the SDK installs two global process handlers at init() time:
| Handler | Severity | What it catches |
|---|---|---|
uncaughtException | fatal | Synchronous errors that propagate to the top of the call stack without being caught |
unhandledRejection | error | Promise rejections not handled with .catch() |
// Automatically captured as fatal
setTimeout(() => {
throw new Error('Unexpected failure');
}, 1000);
// Automatically captured as error
async function fetchData() {
const res = await fetch('https://api.example.com/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
}
fetchData(); // No .catch() — Cognition captures thisThese handlers are cleanly removed during cognition.close() and never interfere with your own handlers.
Manual Error Capture
captureError()
Capture a caught error explicitly with optional context:
try {
await riskyOperation();
} catch (err) {
cognition.captureError(err as Error, {
level: 'error', // Override the default severity
context: {
userId: 'u-123',
action: 'checkout',
cartTotal: 99.99,
},
});
}The context object is merged into the event's extra field alongside any global extra data set via setExtra().
captureMessage()
Capture a plain message string without an Error object:
cognition.captureMessage('User signed up', 'info');
cognition.captureMessage('Payment failed after 3 retries', 'warning');
cognition.captureMessage('Quota limit approaching', 'warning');captureEvent()
Send a fully constructed event of any type through the transport pipeline:
cognition.captureEvent({
type: 'business_metric',
timestamp: Date.now(),
metric: 'order_total',
value: 149.99,
orderId: 'ord-456',
});Custom events pass through the same beforeSend hook, ring buffer, and batching as all built-in event types.
Severity Levels
| Level | Meaning | Default for |
|---|---|---|
fatal | Unrecoverable — process should exit | uncaughtException |
error | Significant error, handled but notable | unhandledRejection, manual captureError() default |
warning | Notable but not an error | Manual capture |
info | Informational | captureMessage() default |
debug | Verbose diagnostic information | Manual capture |
Context Enrichment
Every error event is automatically enriched from multiple sources before being buffered:
Per-capture context (captureError options) ──┐
Global extra (setExtra) ────────────────────┤──► error.extra
Global tags (setTag) ────────────────────┤──► error.tags
User (setUser) ────────────────────┤──► error.user
Breadcrumbs ────────────────────┤──► error.breadcrumbs
Config (environment, release, serverName) ┤──► error.environment / release / serverName
Runtime (node version) ────────────────────┤──► error.runtime
OS (platform, kernel version) ────────────────┘──► error.ossetUser()
Attach user identity to all subsequent events:
cognition.setUser({
id: 'user-123',
email: '[email protected]',
username: 'jane_doe',
});
// Clear user on logout
cognition.setUser(undefined);setTag()
Tags are indexed and searchable in the Console:
cognition.setTag('service', 'payment-api');
cognition.setTag('region', 'us-east-1');
cognition.setTag('version', '2.1.0');setExtra()
Attach arbitrary key-value data:
cognition.setExtra('requestId', 'req-abc-123');
cognition.setExtra('retryCount', 3);
cognition.setExtra('featureFlag', 'new-checkout-flow');Breadcrumbs
Breadcrumbs are a trail of events recorded before an error occurs. When an error is captured, the most recent breadcrumbs are snapshot and attached to the error event.
Automatic Breadcrumbs (Console Patching)
When captureErrors: true, the SDK monkey-patches console methods to silently record breadcrumbs. Original output still happens — Cognition only intercepts, it never suppresses.
| Console Method | Breadcrumb Level |
|---|---|
console.debug | debug |
console.log | info |
console.info | info |
console.warn | warning |
console.error | error |
Original console.* methods are restored during cognition.close().
Manual Breadcrumbs
// Category, message, optional data, optional level
cognition.addBreadcrumb('http', 'GET /api/users → 200', { durationMs: 45 });
cognition.addBreadcrumb('database', 'Fetched user record', { userId: 'u-123' });
cognition.addBreadcrumb('user-action', 'Clicked "Submit Order"');
cognition.addBreadcrumb('navigation', 'Redirected to /checkout', undefined, 'info');Parameters:
| Parameter | Type | Description |
|---|---|---|
category | string | Grouping category: 'http', 'database', 'user-action', etc. |
message | string | Human-readable description |
data | Record<string, unknown>? | Arbitrary structured data |
level | SeverityLevel? | Default: 'info' |
Breadcrumb Buffer
The internal BreadcrumbCollector maintains a circular buffer of the most recent 100 breadcrumbs. When an error occurs, all current breadcrumbs are snapshot and attached to the event — the buffer is not cleared.
interface Breadcrumb {
timestamp: number; // Unix ms
category: string; // e.g. 'console', 'http', 'database'
message: string; // Human-readable description
level: SeverityLevel; // 'fatal' | 'error' | 'warning' | 'info' | 'debug'
data?: Record<string, unknown>;
}Stack Frame Parsing
The SDK parses V8 stack traces into structured StackFrame objects. Given:
Error: Connection refused
at DatabaseClient.connect (src/db/client.ts:45:12)
at async handleRequest (src/routes/users.ts:23:5)
at Layer.handle (node_modules/express/lib/router/layer.js:95:5)
at node:internal/process/task_queues:95:5Produces:
[
{ "function": "DatabaseClient.connect", "filename": "src/db/client.ts", "lineno": 45, "colno": 12, "in_app": true },
{ "function": "async handleRequest", "filename": "src/routes/users.ts", "lineno": 23, "colno": 5, "in_app": true },
{ "function": "Layer.handle", "filename": "node_modules/express/lib/router/layer.js", "lineno": 95, "colno": 5, "in_app": false },
{ "filename": "node:internal/process/task_queues", "lineno": 95, "colno": 5, "in_app": false }
]in_app classification: A frame is in_app: false if its filename contains node_modules or starts with node:. Everything else is in_app: true. This helps the Skytells platform prioritize your application code in analysis.
Error Event Structure
Every captured error produces a fully typed ErrorEvent:
interface ErrorEvent {
type: 'error';
timestamp: number; // Unix ms
error: {
name: string; // e.g. 'TypeError'
message: string; // e.g. 'Cannot read properties of undefined'
stack?: string; // Raw V8 stack trace
frames?: StackFrame[]; // Parsed structured frames
};
level: SeverityLevel; // 'fatal' | 'error' | 'warning' | 'info' | 'debug'
breadcrumbs: Breadcrumb[]; // Recent breadcrumbs
tags: Record<string, string>; // Global tags
extra: Record<string, unknown>; // Global extra + per-capture context
user?: {
id?: string;
email?: string;
username?: string;
};
environment: string; // From config.environment
release: string; // From config.release
serverName: string; // From config.serverName or os.hostname()
runtime: {
name: 'node';
version: string; // e.g. '20'
};
os: {
name: string; // 'darwin', 'linux', 'win32'
version: string; // Kernel version
};
fingerprint?: string[];
context?: Record<string, unknown>;
}Full Example
import { Cognition } from '@skytells/cognition';
const cognition = Cognition.init({
apiKey: process.env.SKYTELLS_API_KEY!,
projectId: process.env.SKYTELLS_PROJECT_ID!,
environment: 'production',
release: process.env.npm_package_version,
});
// Persistent context — attached to all subsequent events
cognition.setUser({ id: 'u-456', username: 'buyer_jane' });
cognition.setTag('service', 'payments');
cognition.setExtra('region', 'us-east-1');
// Breadcrumbs — recorded as the request flows through your system
cognition.addBreadcrumb('http', 'POST /api/charge → started');
cognition.addBreadcrumb('data', 'Fetched wallet balance', { userId: 'u-456' });
try {
await chargeCustomer(order);
} catch (err) {
// Error event will include:
// - Parsed stack frames with in_app classification
// - 2 manual breadcrumbs + any console breadcrumbs
// - User { id: 'u-456', username: 'buyer_jane' }
// - Tags { service: 'payments' }
// - Extra { region: 'us-east-1', orderId: order.id }
// - environment, release, serverName, runtime, os
cognition.captureError(err as Error, {
context: { orderId: order.id },
});
}Related
- Quickstart — Initialize the SDK and send your first event
- Configuration —
captureErrors,beforeSend,environment,releaseoptions - Analytics — View captured errors in the Console and CLI
How is this guide?
Quickstart
Install @skytells/cognition, connect it to your Skytells project, and verify your first events in the Console.
Runtime Observer
Six process health monitors sampling event loop timing, memory, CPU, garbage collection, active handles, and HTTP metrics. Configurable thresholds emit anomaly events when limits are crossed.