- Use one SDK for behaviour, entitlements, and errors so the customer context stays intact.
- Auto-capture should handle the unexpected failures, manual capture should handle the expected catch blocks.
- The useful dashboard groups errors by fingerprint and shows who the failure hurt.
Definitions used in this guide
The sequence of user actions, route changes, and requests that happened before an error fired.
A normalized signature that groups repeated failures together even when line numbers or values vary slightly.
A plain-English explanation of who was affected, what they were doing, and why the error matters to the business.
What should be true before you start?
Before you instrument anything, decide which failures should report automatically and which ones your code should report manually. The goal is one reliable error stream, not overlapping handlers that all shout about the same bug.
- Initialize one SDK at app boot before premium flows and checkout begin.
- Identify the signed-in user as soon as auth resolves so error events land on the right customer.
- List the high-value catch points where you still want manual reporting, such as checkout, restore, export, or team invites.
How should you implement this step by step?
In Crossdeck's model, errors are not a separate product install. The same init that activates analytics and entitlements can also capture uncaught exceptions and unhandled promise rejections. Manual reporting stays available for the failures your app catches on purpose.
- Initialize the web SDK once so global error handlers and event tracking activate together.
- Identify the user before they enter premium or payment flows so every error can be tied back to the customer record.
- Let the automatic handlers catch uncaught exceptions and unhandled rejections instead of re-building that plumbing in parallel.
- Call
Crossdeck.captureError()inside catch blocks for important failures your app recovers from, such as checkout, export, or restore access. - Review grouped errors by fingerprint and customer impact so the team fixes repeated revenue damage first.
| Signal | How it gets captured | Why it matters |
|---|---|---|
| Uncaught exception | SDK global handler | You still see the failures no one wrapped in a try/catch. |
| Unhandled promise rejection | SDK promise rejection handler | Async bugs are common in checkout, auth, and sync flows. |
| Handled business-critical failure | Manual captureError() | Recovered errors still deserve visibility if they affect paying users. |
import { Crossdeck } from "@cross-deck/web"
Crossdeck.init({
publicKey: "cd_pub_live_xxx",
})
if (session?.user?.id) {
await Crossdeck.identify(session.user.id)
}
try {
await processCheckout()
} catch (err) {
Crossdeck.captureError(err)
}
Where do teams make mistakes?
Most teams either under-report errors because they only log in dev, or over-report them because every layer re-sends the same failure.
- Installing a second error SDK that creates a second identity graph and a second dashboard.
- Reporting only raw stack traces with no customer identity attached.
- Capturing every caught validation error even when it is user input, not a product failure.
How does Crossdeck operationalize the workflow?
Crossdeck treats error capture as another event stream on the customer timeline. That means the same record can show the plan the user was on, the feature they were trying to use, and the exception that blocked them.
That joined model is what makes a single SDK valuable. Without it, teams still end up joining purchases, behaviour, and failures by hand after the incident already cost them money.
Frequently asked questions
Do I still need manual captureError() calls if uncaught errors are automatic?
Yes, for important failures that your code catches deliberately. Automatic capture covers the unexpected crashes, while manual capture keeps recovered but important failures visible.
Should every caught exception be reported?
No. Report the failures that reveal a broken product path, a blocked premium action, or a support-relevant issue. Do not turn normal validation into noise.
Why avoid a second SDK?
Because the second SDK creates another identity system, another pricing surface, and another place where the customer context can drift away from the subscription and analytics truth.
Does Crossdeck work across iOS, Android, and web?
Yes. Crossdeck is designed around one customer timeline across Apple, Google Play, Stripe, and web or mobile product events, so the same entitlement and revenue model can travel across surfaces.
What should I do after reading this guide?
Use the CTA in this article to start free or go straight into read error capture docs so you can turn the concept into a verified implementation.
Take this into the product
Open the error docs, wire the SDK once, and verify that your first handled and unhandled exceptions appear on the same customer timeline.