Crashes and errors
Native crashes, handled errors, logs and in-app bug reports — plus why symbolication is what makes any of it readable.
Three different things, often confused:
| What it is | Captured | |
|---|---|---|
| Crash | The process died | Automatically |
| Handled error | You caught it and carried on | You call captureError |
| Log | A breadcrumb for context | You call log |
Crashes are captured for you. The other two are deliberate, because only you know what is worth recording.
Handled errors#
try { await syncCart();} catch (err) { ScaleBun.captureError(err, { where: 'cart_sync', cartId: cart.id, retryCount: attempts, }); showRetryBanner();}The context object is what makes an error actionable. An error report saying
TypeError: undefined is not an object tells you nothing; the same report with the
screen, the entity id and the attempt count usually tells you everything.
Logs#
ScaleBun.log('info', 'Checkout started', { cartValue: 42.5 });ScaleBun.log('warn', 'Retrying payment', { attempt: 2 });ScaleBun.log('error', 'Payment declined', { reason: 'insufficient_funds' });Levels are debug, info, warn, error. Logs attach to the session timeline, so
their value is sequencing — they show what led up to a failure. Log decisions and
transitions, not every function entry.
Testing crash reporting#
ScaleBun.nativeCrash();This genuinely crashes the process. It exists so you can verify the crash pipeline end to end before you need it.
In-app bug reports#
ScaleBun.reportBug('Checkout button does nothing on the summary screen', { screen: 'OrderSummary', cartId: cart.id,});A bug report bundles the description with the current session, so whoever picks it up gets the replay, the logs and the device context rather than a sentence. Wire it to a shake gesture or a support menu item.
Symbolication#
A crash report from a release build is a stack of memory addresses. Symbolication maps those back to your source.
Without uploaded symbols, release crashes are unreadable — not partially readable, unreadable. This is the single most common reason crash reporting looks useless in production, and it is a build-pipeline task, not an SDK setting: upload your iOS dSYMs and Android mapping files as part of each release. Configure it under Settings → Symbolication.
Errors the SDK will not capture for you#
Errors you catch and never report — by design; a swallowed error is invisible.
Errors inside a React error boundary that you do not forward. Call
captureErrorincomponentDidCatch.Promise rejections in code paths with no handler, depending on your runtime configuration. Add a global handler if this matters to you.
Related#
Session replay — seeing what the user did before the crash.
Troubleshooting — when errors are not arriving.
Methods reference —
captureError,log,nativeCrash,reportBugsignatures.