Default Fingerprinting
Automatic grouping by error type and stack trace
Custom Fingerprints
Define your own grouping logic
Smart Deduplication
Similar errors grouped together
Merge & Split
Manually adjust error groups
How Errors Are Grouped
When an error is captured, Sylphx generates a fingerprint to group it with similar errors. This prevents your dashboard from being flooded with duplicate entries and helps you understand the true impact of each unique error.
Errors with the same fingerprint are grouped into a single issue, showing:
- Total occurrence count
- Unique users affected
- First and last seen timestamps
- Trend over time
- All individual events for investigation
Default Fingerprinting Algorithm
By default, Sylphx creates fingerprints using a combination of:
The exception class (TypeError, ReferenceError, etc.)
Normalized message with variables removed
Top frames of the call stack (file, function, line)
The file and function where the error originated
// These two errors will be grouped together:
// Error 1
TypeError: Cannot read property 'name' of undefined
at getUser (src/api/users.ts:42)
at handleRequest (src/server.ts:15)
// Error 2
TypeError: Cannot read property 'name' of undefined
at getUser (src/api/users.ts:42)
at handleRequest (src/server.ts:15)
// Same error type, message, and stack trace = same fingerprintMessage Normalization
// These messages are normalized to the same pattern:
"User 12345 not found" -> "User {id} not found"
"User 67890 not found" -> "User {id} not found"
"Request timeout after 30s" -> "Request timeout after {n}s"
"Request timeout after 60s" -> "Request timeout after {n}s"
"Failed to fetch https://api.example.com/users/123"
-> "Failed to fetch {url}"Custom Fingerprints
For more control over grouping, you can provide a custom fingerprint when capturing errors. This is useful when:
- The default grouping is too broad or too narrow
- You want to group errors by business logic (e.g., payment provider)
- Different stack traces should be grouped together
- The same stack trace should be split into different groups
import { platform } from '@/lib/platform'
// Group all payment failures by provider
try {
await processPayment(provider, amount)
} catch (error) {
await platform.monitoring.captureException({
error,
fingerprint: ['payment-failure', provider],
// Creates groups like:
// - payment-failure-stripe
// - payment-failure-paypal
// - payment-failure-braintree
})
}// Group all checkout errors together regardless of stack trace
await platform.monitoring.captureException({
error,
fingerprint: ['checkout-flow', checkoutStep],
context: {
step: checkoutStep,
cartValue: cart.total,
},
})
// Results in groups:
// - checkout-flow-cart
// - checkout-flow-shipping
// - checkout-flow-payment
// - checkout-flow-confirmationUsing {{ default }}
{{ default }} includes the auto-generated fingerprint. This lets you add custom dimensions while preserving the default grouping behavior.Grouping by Error Type vs Message
Sometimes you want errors grouped purely by type (ignoring the message), or purely by message (ignoring the type). Here's how to achieve both:
// Group all TypeErrors together, regardless of message
await platform.monitoring.captureException({
error,
fingerprint: [error.name], // Just the error type
})
// All of these become one group:
// - TypeError: Cannot read property 'x' of undefined
// - TypeError: Cannot read property 'y' of null
// - TypeError: x is not a functionHandling Similar But Distinct Errors
Sometimes errors look similar but have different root causes. Here's how to keep them separate:
// These look the same but have different causes:
// 1. Network timeout to API
// 2. Network timeout to CDN
// 3. Network timeout to database
try {
await fetchWithTimeout(url, { timeout: 5000 })
} catch (error) {
if (error.name === 'TimeoutError') {
// Parse the URL to determine the service
const service = categorizeUrl(url) // 'api' | 'cdn' | 'database'
await platform.monitoring.captureException({
error,
fingerprint: ['timeout', service],
context: {
url,
service,
timeout: 5000,
},
})
}
}
function categorizeUrl(url: string): string {
if (url.includes('api.')) return 'api'
if (url.includes('cdn.')) return 'cdn'
if (url.includes('db.') || url.includes(':5432')) return 'database'
return 'other'
}Avoid Over-Grouping
Merging and Splitting Groups
From the Sylphx dashboard, you can manually merge or split error groups when the automatic fingerprinting doesn't match your needs.
Merging Groups
Merge groups when you discover that separate issues are actually the same root cause:
Splitting Groups
Split a group when it contains errors that should be tracked separately:
Fingerprint Rules
Fingerprint Rules
Create persistent rules to automatically group errors without code changes:
// Example rule configuration in the dashboard:
{
"name": "Payment provider errors",
"conditions": [
{ "field": "error.message", "contains": "payment" }
],
"fingerprint": [
"payment-error",
"{{ tags.provider }}"
],
"priority": 100 // Higher priority rules are evaluated first
}
// This rule will:
// 1. Match any error with "payment" in the message
// 2. Group by the provider tag
// 3. Override the default fingerprint| Property | Type | Description |
|---|---|---|
namerequired | string | Human-readable name for the rule |
conditionsrequired | Condition[] | Conditions that must match for the rule to apply |
fingerprintrequired | string[] | The fingerprint to use when conditions match |
priority | number= 0 | Rule evaluation order (higher = first) |
enabled | boolean= true | Whether the rule is active |
Best Practices
Start with defaults
The default fingerprinting works well for most cases. Only customize when you see grouping issues.
Use meaningful fingerprints
Choose fingerprint values that are stable and meaningful, like feature names or error categories.
Include context
Even with custom fingerprints, include rich context in your error reports for debugging.
Review periodically
Check your error groups regularly to ensure similar issues are grouped appropriately.