@danieljvdm/dev-kit 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/package.json +1 -1
- package/skill-sources.jsonc +2 -33
- package/skill-sources.lock.json +15 -117
- package/skills/animate/LICENSE +21 -0
- package/skills/animate/NOTICE +10 -0
- package/skills/animate/SKILL.md +34 -0
- package/skills/animate/references/gestures.md +27 -0
- package/skills/animate/references/glossary.md +136 -0
- package/skills/animate/references/implementation.md +22 -0
- package/skills/animate/references/opportunities.md +18 -0
- package/skills/animate/references/principles.md +48 -0
- package/skills/animate/references/review.md +19 -0
- package/skills/cloudflare-workers/LICENSE +202 -0
- package/skills/cloudflare-workers/NOTICE +9 -0
- package/skills/cloudflare-workers/SKILL.md +26 -0
- package/skills/cloudflare-workers/references/durable-objects.md +68 -0
- package/skills/cloudflare-workers/references/sandbox.md +48 -0
- package/skills/cloudflare-workers/references/workers.md +63 -0
- package/skills/cloudflare-workers/references/wrangler.md +56 -0
- package/skills/design-ui/LICENSE +21 -0
- package/skills/design-ui/NOTICE +8 -0
- package/skills/design-ui/SKILL.md +29 -0
- package/skills/design-ui/references/appearance.md +22 -0
- package/skills/design-ui/references/components.md +33 -0
- package/skills/design-ui/references/exploration.md +50 -0
- package/skills/design-ui/references/libraries.md +39 -0
- package/skills/design-ui/references/themes.md +23 -0
- package/skills/dev-kit/SKILL.md +19 -38
- package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
- package/skills/dev-kit/references/skills.md +2 -2
- package/skills/effect-development/SKILL.md +27 -0
- package/skills/effect-development/agents/openai.yaml +4 -0
- package/skills/effect-development/references/api/index.md +32 -0
- package/skills/effect-development/references/api/schema-codecs.md +15 -0
- package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
- package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
- package/skills/effect-development/references/atom/index.md +40 -0
- package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
- package/skills/effect-development/references/cli/index.md +39 -0
- package/skills/effect-development/references/setup.md +15 -0
- package/skills/open-pull-request/SKILL.md +10 -70
- package/skills/open-pull-request/references/evidence.md +22 -0
- package/skills/open-pull-request/references/explanation.md +21 -0
- package/skills/open-pull-request/references/publication.md +21 -0
- package/skills/sentry/LICENSE +202 -0
- package/skills/sentry/LICENSE-UPSTREAM +21 -0
- package/skills/sentry/NOTICE +14 -0
- package/skills/sentry/SKILL.md +33 -0
- package/skills/sentry/references/alert-payloads.md +105 -0
- package/skills/sentry/references/alerts.md +17 -0
- package/skills/sentry/references/artifacts.md +25 -0
- package/skills/sentry/references/auth-token.md +65 -0
- package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
- package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
- package/skills/sentry/references/concepts/crons.md +50 -0
- package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
- package/skills/sentry/references/concepts/errors.md +40 -0
- package/skills/sentry/references/concepts/logging.md +85 -0
- package/skills/sentry/references/concepts/metrics.md +49 -0
- package/skills/sentry/references/concepts/monitors.md +78 -0
- package/skills/sentry/references/concepts/profiling.md +38 -0
- package/skills/sentry/references/concepts/reduce-volume.md +49 -0
- package/skills/sentry/references/concepts/releases.md +43 -0
- package/skills/sentry/references/concepts/session-replay.md +35 -0
- package/skills/sentry/references/concepts/tracing.md +54 -0
- package/skills/sentry/references/concepts/user-feedback.md +36 -0
- package/skills/sentry/references/debug-artifacts/android.md +68 -0
- package/skills/sentry/references/debug-artifacts/apple.md +96 -0
- package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
- package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
- package/skills/sentry/references/debug-artifacts/index.md +75 -0
- package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
- package/skills/sentry/references/debug-artifacts/matching.md +73 -0
- package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
- package/skills/sentry/references/first-error-setup.md +25 -0
- package/skills/sentry/references/instrumentation.md +30 -0
- package/skills/sentry/references/issues.md +32 -0
- package/skills/sentry/references/new-project.md +17 -0
- package/skills/sentry/references/otel-exporter.md +30 -0
- package/skills/sentry/references/release-workflow.md +31 -0
- package/skills/sentry/references/releases/ci-pipeline.md +214 -0
- package/skills/sentry/references/releases/index.md +93 -0
- package/skills/sentry/references/releases/suspect-commits.md +155 -0
- package/skills/sentry/references/releases/tagging.md +131 -0
- package/skills/sentry/references/releases/troubleshooting.md +67 -0
- package/skills/sentry/references/sdks/android/crons.md +305 -0
- package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
- package/skills/sentry/references/sdks/android/index.md +748 -0
- package/skills/sentry/references/sdks/android/integrations.md +48 -0
- package/skills/sentry/references/sdks/android/logging.md +374 -0
- package/skills/sentry/references/sdks/android/metrics.md +288 -0
- package/skills/sentry/references/sdks/android/profiling.md +397 -0
- package/skills/sentry/references/sdks/android/session-replay.md +406 -0
- package/skills/sentry/references/sdks/android/tracing.md +861 -0
- package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
- package/skills/sentry/references/sdks/browser/index.md +714 -0
- package/skills/sentry/references/sdks/browser/logging.md +315 -0
- package/skills/sentry/references/sdks/browser/profiling.md +236 -0
- package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
- package/skills/sentry/references/sdks/browser/tracing.md +561 -0
- package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
- package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
- package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
- package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
- package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
- package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
- package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
- package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
- package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
- package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
- package/skills/sentry/references/sdks/cocoa/index.md +497 -0
- package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
- package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
- package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
- package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
- package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
- package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
- package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
- package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
- package/skills/sentry/references/sdks/dotnet/index.md +614 -0
- package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
- package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
- package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
- package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
- package/skills/sentry/references/sdks/elixir/crons.md +371 -0
- package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
- package/skills/sentry/references/sdks/elixir/index.md +383 -0
- package/skills/sentry/references/sdks/elixir/logging.md +239 -0
- package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
- package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
- package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
- package/skills/sentry/references/sdks/flutter/index.md +728 -0
- package/skills/sentry/references/sdks/flutter/logging.md +387 -0
- package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
- package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
- package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
- package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
- package/skills/sentry/references/sdks/go/crons.md +270 -0
- package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
- package/skills/sentry/references/sdks/go/index.md +324 -0
- package/skills/sentry/references/sdks/go/logging.md +354 -0
- package/skills/sentry/references/sdks/go/metrics.md +273 -0
- package/skills/sentry/references/sdks/go/profiling.md +46 -0
- package/skills/sentry/references/sdks/go/tracing.md +366 -0
- package/skills/sentry/references/sdks/index.md +41 -0
- package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
- package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
- package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
- package/skills/sentry/references/sdks/nestjs/index.md +699 -0
- package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
- package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
- package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
- package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
- package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
- package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
- package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
- package/skills/sentry/references/sdks/nextjs/index.md +491 -0
- package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
- package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
- package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
- package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
- package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
- package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
- package/skills/sentry/references/sdks/node/crons.md +432 -0
- package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
- package/skills/sentry/references/sdks/node/index.md +942 -0
- package/skills/sentry/references/sdks/node/logging.md +380 -0
- package/skills/sentry/references/sdks/node/metrics.md +278 -0
- package/skills/sentry/references/sdks/node/profiling.md +373 -0
- package/skills/sentry/references/sdks/node/tracing.md +878 -0
- package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
- package/skills/sentry/references/sdks/php/crons.md +265 -0
- package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
- package/skills/sentry/references/sdks/php/index.md +362 -0
- package/skills/sentry/references/sdks/php/laravel.md +542 -0
- package/skills/sentry/references/sdks/php/logging.md +242 -0
- package/skills/sentry/references/sdks/php/metrics.md +193 -0
- package/skills/sentry/references/sdks/php/profiling.md +115 -0
- package/skills/sentry/references/sdks/php/symfony.md +552 -0
- package/skills/sentry/references/sdks/php/tracing.md +516 -0
- package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
- package/skills/sentry/references/sdks/python/crons.md +218 -0
- package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
- package/skills/sentry/references/sdks/python/index.md +361 -0
- package/skills/sentry/references/sdks/python/logging.md +234 -0
- package/skills/sentry/references/sdks/python/metrics.md +154 -0
- package/skills/sentry/references/sdks/python/profiling.md +120 -0
- package/skills/sentry/references/sdks/python/tracing.md +364 -0
- package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
- package/skills/sentry/references/sdks/react/index.md +492 -0
- package/skills/sentry/references/sdks/react/logging.md +364 -0
- package/skills/sentry/references/sdks/react/profiling.md +322 -0
- package/skills/sentry/references/sdks/react/react-features.md +1272 -0
- package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
- package/skills/sentry/references/sdks/react/tracing.md +1415 -0
- package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
- package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
- package/skills/sentry/references/sdks/react-native/index.md +1030 -0
- package/skills/sentry/references/sdks/react-native/logging.md +444 -0
- package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
- package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
- package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
- package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
- package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
- package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
- package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
- package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
- package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
- package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
- package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
- package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
- package/skills/sentry/references/sdks/ruby/crons.md +184 -0
- package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
- package/skills/sentry/references/sdks/ruby/index.md +297 -0
- package/skills/sentry/references/sdks/ruby/logging.md +168 -0
- package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
- package/skills/sentry/references/sdks/ruby/migration.md +321 -0
- package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
- package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
- package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
- package/skills/sentry/references/sdks/svelte/index.md +467 -0
- package/skills/sentry/references/sdks/svelte/logging.md +344 -0
- package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
- package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
- package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
- package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
- package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
- package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
- package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
- package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
- package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
- package/skills/sentry/references/search-query-language.md +226 -0
- package/skills/sentry/references/semantics/angular.md +7 -0
- package/skills/sentry/references/semantics/app.md +28 -0
- package/skills/sentry/references/semantics/art.md +17 -0
- package/skills/sentry/references/semantics/aws.md +43 -0
- package/skills/sentry/references/semantics/browser.md +34 -0
- package/skills/sentry/references/semantics/cache.md +12 -0
- package/skills/sentry/references/semantics/client.md +8 -0
- package/skills/sentry/references/semantics/cloud.md +12 -0
- package/skills/sentry/references/semantics/cloudflare.md +23 -0
- package/skills/sentry/references/semantics/code.md +11 -0
- package/skills/sentry/references/semantics/culture.md +11 -0
- package/skills/sentry/references/semantics/db.md +21 -0
- package/skills/sentry/references/semantics/device.md +43 -0
- package/skills/sentry/references/semantics/error.md +7 -0
- package/skills/sentry/references/semantics/event.md +8 -0
- package/skills/sentry/references/semantics/exception.md +10 -0
- package/skills/sentry/references/semantics/faas.md +19 -0
- package/skills/sentry/references/semantics/file.md +8 -0
- package/skills/sentry/references/semantics/flag.md +7 -0
- package/skills/sentry/references/semantics/gcp.md +16 -0
- package/skills/sentry/references/semantics/gen_ai.md +53 -0
- package/skills/sentry/references/semantics/general.md +11 -0
- package/skills/sentry/references/semantics/graphql.md +9 -0
- package/skills/sentry/references/semantics/grpc.md +19 -0
- package/skills/sentry/references/semantics/http.md +34 -0
- package/skills/sentry/references/semantics/index.md +63 -0
- package/skills/sentry/references/semantics/jsonrpc.md +8 -0
- package/skills/sentry/references/semantics/jvm.md +12 -0
- package/skills/sentry/references/semantics/koa.md +7 -0
- package/skills/sentry/references/semantics/logger.md +7 -0
- package/skills/sentry/references/semantics/mcp.md +37 -0
- package/skills/sentry/references/semantics/mdc.md +7 -0
- package/skills/sentry/references/semantics/messaging.md +23 -0
- package/skills/sentry/references/semantics/middleware.md +7 -0
- package/skills/sentry/references/semantics/navigation.md +9 -0
- package/skills/sentry/references/semantics/nel.md +11 -0
- package/skills/sentry/references/semantics/network.md +17 -0
- package/skills/sentry/references/semantics/os.md +15 -0
- package/skills/sentry/references/semantics/otel.md +10 -0
- package/skills/sentry/references/semantics/params.md +7 -0
- package/skills/sentry/references/semantics/process.md +14 -0
- package/skills/sentry/references/semantics/react.md +7 -0
- package/skills/sentry/references/semantics/remix.md +7 -0
- package/skills/sentry/references/semantics/resource.md +7 -0
- package/skills/sentry/references/semantics/rpc.md +10 -0
- package/skills/sentry/references/semantics/score.md +10 -0
- package/skills/sentry/references/semantics/sentry.md +69 -0
- package/skills/sentry/references/semantics/server.md +8 -0
- package/skills/sentry/references/semantics/service.md +8 -0
- package/skills/sentry/references/semantics/session.md +7 -0
- package/skills/sentry/references/semantics/state.md +7 -0
- package/skills/sentry/references/semantics/thread.md +8 -0
- package/skills/sentry/references/semantics/timber.md +7 -0
- package/skills/sentry/references/semantics/trpc.md +8 -0
- package/skills/sentry/references/semantics/ui.md +18 -0
- package/skills/sentry/references/semantics/url.md +15 -0
- package/skills/sentry/references/semantics/user.md +17 -0
- package/skills/sentry/references/semantics/user_agent.md +7 -0
- package/skills/sentry/references/semantics/vercel.md +42 -0
- package/skills/sentry/references/setup-verification.md +39 -0
- package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
- package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
- package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
- package/skills/sentry/references/snapshots/index.md +19 -0
- package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
- package/skills/sentry/references/snapshots/snapshots.md +123 -0
- package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
- package/skills/testing/LICENSE +21 -0
- package/skills/testing/NOTICE +7 -0
- package/skills/testing/SKILL.md +13 -19
- package/skills/testing/agents/openai.yaml +1 -2
- package/skills/testing/references/selection.md +23 -0
- package/skills/testing/references/tdd.md +19 -0
- package/skills/testing/references/test-design.md +17 -0
- package/src/catalog.ts +1 -7
- package/skills/build-effect-apis/SKILL.md +0 -81
- package/skills/build-effect-apis/agents/openai.yaml +0 -4
- package/skills/build-effect-clis/SKILL.md +0 -92
- package/skills/build-effect-clis/agents/openai.yaml +0 -4
- package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
- package/skills/effect-atom-state/SKILL.md +0 -97
- package/skills/effect-atom-state/agents/openai.yaml +0 -4
- package/skills/effect-ts/SKILL.md +0 -35
- package/skills/effect-ts/agents/openai.yaml +0 -4
- /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
- /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
|
@@ -0,0 +1,1481 @@
|
|
|
1
|
+
# Error Monitoring & Crash Reporting — Sentry React Native SDK
|
|
2
|
+
|
|
3
|
+
> **Minimum SDK:** `@sentry/react-native` ≥ 6.0.0 (≥ 8.0.0 recommended) **Native SDKs:**
|
|
4
|
+
> `sentry-cocoa` (iOS/tvOS/macOS) · `sentry-android` (Java + NDK) **React Native:**
|
|
5
|
+
> 0.71+ required for Fabric renderer support
|
|
6
|
+
|
|
7
|
+
React Native is unique: errors can originate from three different layers — the
|
|
8
|
+
**JavaScript runtime**, **native iOS** (ObjC/Swift, Mach exceptions), or **native
|
|
9
|
+
Android** (Java, JNI/C++ via NDK). The Sentry RN SDK bridges all three.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
1. [Core Capture APIs](#1-core-capture-apis)
|
|
16
|
+
2. [Native Crash Handling — iOS & Android](#2-native-crash-handling--ios--android)
|
|
17
|
+
3. [ANR / App Hang Detection](#3-anr--app-hang-detection)
|
|
18
|
+
4. [Unhandled Promise Rejections](#4-unhandled-promise-rejections)
|
|
19
|
+
5. [Sentry.wrap(App) — Top-Level Error Boundary](#5-sentrywrapapp--top-level-error-boundary)
|
|
20
|
+
6. [ErrorBoundary Component](#6-errorboundary-component)
|
|
21
|
+
7. [Scope Management](#7-scope-management)
|
|
22
|
+
8. [Context Enrichment — Tags, User, Extra, Contexts](#8-context-enrichment--tags-user-extra-contexts)
|
|
23
|
+
9. [Breadcrumbs — Automatic & Manual](#9-breadcrumbs--automatic--manual)
|
|
24
|
+
10. [beforeSend / beforeSendTransaction Hooks](#10-beforesend--beforesendtransaction-hooks)
|
|
25
|
+
11. [Fingerprinting & Grouping](#11-fingerprinting--grouping)
|
|
26
|
+
12. [Event Processors](#12-event-processors)
|
|
27
|
+
13. [Attachments — Screenshots & View Hierarchy](#13-attachments--screenshots--view-hierarchy)
|
|
28
|
+
14. [Redux Integration](#14-redux-integration)
|
|
29
|
+
15. [Device & App Context](#15-device--app-context)
|
|
30
|
+
16. [Release Health & Sessions](#16-release-health--sessions)
|
|
31
|
+
17. [Offline Event Caching](#17-offline-event-caching)
|
|
32
|
+
18. [Default Integrations](#18-default-integrations)
|
|
33
|
+
19. [Full init() Options Reference](#19-full-init-options-reference)
|
|
34
|
+
20. [Quick Reference Cheatsheet](#20-quick-reference-cheatsheet)
|
|
35
|
+
21. [Troubleshooting](#21-troubleshooting)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1. Core Capture APIs
|
|
40
|
+
|
|
41
|
+
Three fundamental data concepts:
|
|
42
|
+
|
|
43
|
+
- **Event** — a single submission to Sentry (exception, message, or raw event)
|
|
44
|
+
- **Issue** — a group of similar events clustered by Sentry
|
|
45
|
+
- **Capturing** — the act of reporting an event
|
|
46
|
+
|
|
47
|
+
### `Sentry.captureException(error, context?)`
|
|
48
|
+
|
|
49
|
+
Captures any thrown `Error` (or non-Error value) and sends it to Sentry.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import * as Sentry from "@sentry/react-native";
|
|
53
|
+
|
|
54
|
+
// Basic usage
|
|
55
|
+
try {
|
|
56
|
+
aFunctionThatMightFail();
|
|
57
|
+
} catch (err) {
|
|
58
|
+
Sentry.captureException(err);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// With inline context (plain object)
|
|
62
|
+
Sentry.captureException(new Error("something went wrong"), {
|
|
63
|
+
tags: { section: "checkout" },
|
|
64
|
+
user: { email: "user@example.com" },
|
|
65
|
+
extra: { orderId: "abc-123" },
|
|
66
|
+
level: "warning",
|
|
67
|
+
fingerprint: ["{{ default }}", "checkout-error"],
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// With a scope callback — clones scope for this capture only
|
|
71
|
+
Sentry.captureException(new Error("something went wrong"), (scope) => {
|
|
72
|
+
scope.setTag("section", "articles");
|
|
73
|
+
scope.setLevel("warning");
|
|
74
|
+
return scope;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// New Scope instance — merges with global scope
|
|
78
|
+
const scope = new Sentry.Scope();
|
|
79
|
+
scope.setTag("section", "articles");
|
|
80
|
+
Sentry.captureException(new Error("something went wrong"), scope);
|
|
81
|
+
|
|
82
|
+
// Isolate entirely — return the scope from a function to ignore global attrs
|
|
83
|
+
Sentry.captureException(new Error("clean slate"), () => scope);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `Sentry.captureMessage(message, level?)`
|
|
87
|
+
|
|
88
|
+
Sends a textual message.
|
|
89
|
+
Useful for non-exception events or informational milestones.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Default level is "info"
|
|
93
|
+
Sentry.captureMessage("Something noteworthy happened");
|
|
94
|
+
|
|
95
|
+
// Explicit severity level
|
|
96
|
+
// "fatal" | "error" | "warning" | "log" | "info" | "debug"
|
|
97
|
+
Sentry.captureMessage("Payment declined", "warning");
|
|
98
|
+
Sentry.captureMessage("Critical system failure", "fatal");
|
|
99
|
+
Sentry.captureMessage("Debug checkpoint reached", "debug");
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `Sentry.captureEvent(event)`
|
|
103
|
+
|
|
104
|
+
Low-level method to send a fully constructed Sentry event object.
|
|
105
|
+
Used for advanced cases where you build the event manually.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
Sentry.captureEvent({
|
|
109
|
+
message: "Manual event",
|
|
110
|
+
level: "error",
|
|
111
|
+
tags: { custom_tag: "value" },
|
|
112
|
+
extra: { arbitrary_data: true },
|
|
113
|
+
fingerprint: ["my-custom-fingerprint"],
|
|
114
|
+
timestamp: Date.now() / 1000,
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Error Levels
|
|
119
|
+
|
|
120
|
+
| Level | Use Case |
|
|
121
|
+
| --------- | -------------------------------------- |
|
|
122
|
+
| `fatal` | App crash, total loss of functionality |
|
|
123
|
+
| `error` | Feature broken, user action failed |
|
|
124
|
+
| `warning` | Degraded state, non-critical failure |
|
|
125
|
+
| `info` | Informational, noteworthy events |
|
|
126
|
+
| `log` | Low-priority operational logs |
|
|
127
|
+
| `debug` | Development diagnostics |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 2. Native Crash Handling — iOS & Android
|
|
132
|
+
|
|
133
|
+
The React Native SDK delegates to two native SDKs for platform-level crash capture:
|
|
134
|
+
|
|
135
|
+
- **iOS/tvOS/macOS** — `sentry-cocoa`
|
|
136
|
+
- **Android** — `sentry-android` (Java/Kotlin + NDK for C/C++)
|
|
137
|
+
|
|
138
|
+
### How Native Crash Capture Works
|
|
139
|
+
|
|
140
|
+
Native crashes (segfaults, SIGSEGV, unhandled C++ exceptions, OOM kills) are captured
|
|
141
|
+
**entirely at the OS level** — not in JavaScript.
|
|
142
|
+
The crash handler is registered during native SDK initialization.
|
|
143
|
+
Crash reports are:
|
|
144
|
+
|
|
145
|
+
1. Persisted to disk in binary envelope format at crash time
|
|
146
|
+
2. **Not sent at crash time** — queued and sent on the **next app launch**
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
iOS: [crash] → written to disk by sentry-cocoa
|
|
150
|
+
→ [next launch] → sentry-cocoa reads and transmits
|
|
151
|
+
|
|
152
|
+
Android: [crash] → written to disk by sentry-android
|
|
153
|
+
→ [next app restart] → sentry-android reads and transmits
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Native Configuration Options
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
Sentry.init({
|
|
160
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
161
|
+
|
|
162
|
+
// Disable all native SDK functionality (JS layer only)
|
|
163
|
+
enableNative: false,
|
|
164
|
+
|
|
165
|
+
// Prevent native layer from capturing hard crashes
|
|
166
|
+
enableNativeCrashHandling: false,
|
|
167
|
+
|
|
168
|
+
// Manually initialize native SDKs yourself (advanced)
|
|
169
|
+
autoInitializeNativeSdk: false,
|
|
170
|
+
|
|
171
|
+
// Sync Android Java scope data to NDK layer (for C/C++ crash context)
|
|
172
|
+
enableNdkScopeSync: true,
|
|
173
|
+
|
|
174
|
+
// Android 12+: use ApplicationExitInfo for enhanced tombstone reports
|
|
175
|
+
enableTombstone: true,
|
|
176
|
+
|
|
177
|
+
// Attach all thread states to Android events (has a performance impact)
|
|
178
|
+
attachThreads: false,
|
|
179
|
+
|
|
180
|
+
// Called after native SDKs have finished initializing
|
|
181
|
+
onReady: () => {
|
|
182
|
+
console.log("Sentry native SDKs initialized");
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Offline Caching Behavior
|
|
188
|
+
|
|
189
|
+
| Platform | Offline Behavior |
|
|
190
|
+
| ----------- | ------------------------------------------------------------------ |
|
|
191
|
+
| **Android** | Events cached on device; transmitted on **app restart** |
|
|
192
|
+
| **iOS** | Events cached on device; transmitted when the **next event fires** |
|
|
193
|
+
|
|
194
|
+
### Linked Errors (Chained `.cause`)
|
|
195
|
+
|
|
196
|
+
The `NativeLinkedErrors` integration (enabled by default) reads the `.cause` property on
|
|
197
|
+
errors recursively, linking the error chain up to **5 levels deep**:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
try {
|
|
201
|
+
await fetchMovieReviews(movie);
|
|
202
|
+
} catch (originalError) {
|
|
203
|
+
const wrapperError = new Error(`Failed to fetch reviews for: ${movie}`);
|
|
204
|
+
wrapperError.cause = originalError; // SDK reads this chain
|
|
205
|
+
Sentry.captureException(wrapperError);
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Native SDK Log Forwarding
|
|
210
|
+
|
|
211
|
+
The SDK can forward native SDK internal log messages (from iOS and Android native
|
|
212
|
+
layers) to the JavaScript console.
|
|
213
|
+
This is a **debugging tool** — it surfaces native SDK diagnostics in Metro without
|
|
214
|
+
requiring Xcode or Logcat.
|
|
215
|
+
|
|
216
|
+
**Requirements:** `debug: true` must be enabled in `Sentry.init`.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import * as Sentry from "@sentry/react-native";
|
|
220
|
+
|
|
221
|
+
Sentry.init({
|
|
222
|
+
dsn: "YOUR_DSN",
|
|
223
|
+
debug: true, // required — native logs are only forwarded when debug is enabled
|
|
224
|
+
|
|
225
|
+
onNativeLog: ({ level, component, message }) => {
|
|
226
|
+
// Use consoleSandbox to avoid feedback loops with Sentry's console integration
|
|
227
|
+
Sentry.consoleSandbox(() => {
|
|
228
|
+
console.log(`[Sentry Native] [${level.toUpperCase()}] [${component}] ${message}`);
|
|
229
|
+
});
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
| Parameter | Type | Values |
|
|
235
|
+
| ----------- | -------- | ------------------------------------------------------ |
|
|
236
|
+
| `level` | `string` | `"debug"`, `"info"`, `"warning"`, `"error"`, `"fatal"` |
|
|
237
|
+
| `component` | `string` | Native module name (e.g., `"Sentry"`) |
|
|
238
|
+
| `message` | `string` | The log message from the native SDK |
|
|
239
|
+
|
|
240
|
+
> **Always use `Sentry.consoleSandbox()`** inside the callback.
|
|
241
|
+
> Without it, your `console.log` call may be intercepted by the Sentry `Breadcrumbs`
|
|
242
|
+
> integration, which creates a breadcrumb that triggers another log event — an infinite
|
|
243
|
+
> loop.
|
|
244
|
+
|
|
245
|
+
> **Never enable `debug: true` in production.** Native log forwarding is for local
|
|
246
|
+
> development and CI debugging only.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 3. ANR / App Hang Detection
|
|
251
|
+
|
|
252
|
+
### Android — Application Not Responding (ANR)
|
|
253
|
+
|
|
254
|
+
ANR detection is handled by the native `sentry-android` SDK. Android’s OS flags an ANR
|
|
255
|
+
when:
|
|
256
|
+
|
|
257
|
+
- An **activity doesn’t respond to user input within 5 seconds**
|
|
258
|
+
- A **broadcast receiver doesn’t complete within 10 seconds**
|
|
259
|
+
|
|
260
|
+
The SDK detects this via a watchdog thread monitoring the main thread.
|
|
261
|
+
When the UI thread is blocked, an ANR event is created and sent to Sentry.
|
|
262
|
+
ANR detection on Android is **always enabled** via the native SDK and is not
|
|
263
|
+
configurable from JavaScript.
|
|
264
|
+
|
|
265
|
+
### iOS / tvOS / macOS — App Hangs
|
|
266
|
+
|
|
267
|
+
On Apple platforms, `sentry-cocoa` monitors the main thread with a watchdog.
|
|
268
|
+
Any block exceeding the configured threshold triggers an error event.
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
Sentry.init({
|
|
272
|
+
dsn: "___PUBLIC_DSN___",
|
|
273
|
+
|
|
274
|
+
// Disable app hang tracking (Apple platforms only)
|
|
275
|
+
enableAppHangTracking: false,
|
|
276
|
+
|
|
277
|
+
// Detection threshold in seconds (default: 2)
|
|
278
|
+
// Main thread must be blocked longer than this value to trigger
|
|
279
|
+
appHangTimeoutInterval: 1,
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
> **Note:** `enableAppHangTracking` and `appHangTimeoutInterval` apply to **iOS, tvOS,
|
|
284
|
+
> and macOS** only.
|
|
285
|
+
|
|
286
|
+
### iOS Watchdog Terminations & OOM
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
Sentry.init({
|
|
290
|
+
// Track out-of-memory kills and watchdog terminations on iOS (default: true)
|
|
291
|
+
enableWatchdogTerminationTracking: true,
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 4. Unhandled Promise Rejections
|
|
298
|
+
|
|
299
|
+
The SDK automatically captures unhandled promise rejections via the built-in
|
|
300
|
+
`UnhandledRejection` integration.
|
|
301
|
+
Any promise that rejects without a `.catch()` or `try/catch` is captured as a Sentry
|
|
302
|
+
error event with no configuration needed.
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// This is automatically captured by Sentry:
|
|
306
|
+
async function doSomething() {
|
|
307
|
+
throw new Error("Unhandled rejection");
|
|
308
|
+
}
|
|
309
|
+
doSomething(); // No await, no .catch()
|
|
310
|
+
|
|
311
|
+
// To disable (if you handle these yourself elsewhere):
|
|
312
|
+
Sentry.init({
|
|
313
|
+
integrations: (integrations) => integrations.filter((i) => i.name !== "UnhandledRejection"),
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 5. `Sentry.wrap(App)` — Top-Level Error Boundary
|
|
320
|
+
|
|
321
|
+
`Sentry.wrap` wraps your **root component** and should be used in every React Native app
|
|
322
|
+
using Sentry.
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
// index.js / app entry point
|
|
326
|
+
import { AppRegistry } from "react-native";
|
|
327
|
+
import * as Sentry from "@sentry/react-native";
|
|
328
|
+
import App from "./src/App";
|
|
329
|
+
import { name as appName } from "./app.json";
|
|
330
|
+
|
|
331
|
+
Sentry.init({
|
|
332
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
AppRegistry.registerComponent(appName, () => Sentry.wrap(App));
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**What `Sentry.wrap` does:**
|
|
339
|
+
|
|
340
|
+
| Capability | Description |
|
|
341
|
+
| ------------------------------- | ------------------------------------------------------------ |
|
|
342
|
+
| **React render error boundary** | Catches errors thrown during component rendering |
|
|
343
|
+
| **UI interaction tracking** | Records touch events as `ui.click` breadcrumbs automatically |
|
|
344
|
+
| **User Feedback Widget** | `Sentry.showFeedbackWidget()` requires this wrapper |
|
|
345
|
+
| **Session Replay buffering** | Buffers pre-error session data for the feedback widget |
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## 6. `ErrorBoundary` Component
|
|
350
|
+
|
|
351
|
+
`Sentry.ErrorBoundary` is a React error boundary that catches render-time errors,
|
|
352
|
+
reports them to Sentry with full React component stack context, and renders a fallback
|
|
353
|
+
UI.
|
|
354
|
+
|
|
355
|
+
### Basic Usage
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import * as Sentry from "@sentry/react-native";
|
|
359
|
+
|
|
360
|
+
function App() {
|
|
361
|
+
return (
|
|
362
|
+
<Sentry.ErrorBoundary fallback={<Text>An error has occurred</Text>}>
|
|
363
|
+
<Dashboard />
|
|
364
|
+
</Sentry.ErrorBoundary>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Fallback as a Function
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import * as Sentry from "@sentry/react-native";
|
|
373
|
+
|
|
374
|
+
function App() {
|
|
375
|
+
return (
|
|
376
|
+
<Sentry.ErrorBoundary
|
|
377
|
+
fallback={({ error, componentStack, resetError }) => (
|
|
378
|
+
<View style={styles.errorContainer}>
|
|
379
|
+
<Text style={styles.title}>Something went wrong</Text>
|
|
380
|
+
<Text style={styles.message}>{error.toString()}</Text>
|
|
381
|
+
<Text style={styles.stack}>{componentStack}</Text>
|
|
382
|
+
<Button title="Try again" onPress={resetError} />
|
|
383
|
+
</View>
|
|
384
|
+
)}
|
|
385
|
+
>
|
|
386
|
+
<MainContent />
|
|
387
|
+
</Sentry.ErrorBoundary>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
The fallback function receives:
|
|
393
|
+
|
|
394
|
+
- `error` — the thrown error object
|
|
395
|
+
- `componentStack` — React’s component stack trace string
|
|
396
|
+
- `resetError` — function to clear error state and re-render children
|
|
397
|
+
|
|
398
|
+
### Higher-Order Component (HOC) Pattern
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import * as Sentry from "@sentry/react-native";
|
|
402
|
+
|
|
403
|
+
const SafeDashboard = Sentry.withErrorBoundary(Dashboard, {
|
|
404
|
+
fallback: <View><Text>Dashboard unavailable</Text></View>,
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Multiple Boundaries with Contextual Tags
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
function App() {
|
|
412
|
+
return (
|
|
413
|
+
<View>
|
|
414
|
+
<Sentry.ErrorBoundary
|
|
415
|
+
fallback={<SidebarFallback />}
|
|
416
|
+
beforeCapture={(scope) => scope.setTag("section", "sidebar")}
|
|
417
|
+
>
|
|
418
|
+
<Sidebar />
|
|
419
|
+
</Sentry.ErrorBoundary>
|
|
420
|
+
|
|
421
|
+
<Sentry.ErrorBoundary
|
|
422
|
+
fallback={<ContentFallback />}
|
|
423
|
+
beforeCapture={(scope) => scope.setTag("section", "content")}
|
|
424
|
+
>
|
|
425
|
+
<MainContent />
|
|
426
|
+
</Sentry.ErrorBoundary>
|
|
427
|
+
</View>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Nesting error boundaries allows granular isolation: an error in `Sidebar` won’t crash
|
|
433
|
+
`MainContent`, and each boundary tags its errors with a `section` for easy filtering in
|
|
434
|
+
Sentry.
|
|
435
|
+
|
|
436
|
+
### Show User Feedback Dialog on Error
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
<Sentry.ErrorBoundary
|
|
440
|
+
showDialog // auto-opens user feedback dialog when error is caught
|
|
441
|
+
fallback={<ErrorScreen />}
|
|
442
|
+
>
|
|
443
|
+
<App />
|
|
444
|
+
</Sentry.ErrorBoundary>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Full Props Reference
|
|
448
|
+
|
|
449
|
+
| Prop | Type | Description |
|
|
450
|
+
| --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
451
|
+
| `fallback` | `ReactNode \| ({ error, componentStack, resetError }) => ReactNode` | UI rendered when an error is caught |
|
|
452
|
+
| `showDialog` | `boolean` | Open User Feedback widget on error |
|
|
453
|
+
| `dialogOptions` | `object` | Options passed to the feedback dialog |
|
|
454
|
+
| `onError` | `(error, componentStack, eventId) => void` | Called when an error is caught; useful for state propagation |
|
|
455
|
+
| `beforeCapture` | `(scope, error, componentStack) => void` | Called before sending to Sentry; add tags/context here |
|
|
456
|
+
| `onMount` | `() => void` | Called on `componentDidMount` |
|
|
457
|
+
| `onUnmount` | `() => void` | Called on `componentWillUnmount` |
|
|
458
|
+
|
|
459
|
+
### Manual Error Boundary (Class Component)
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
import React from "react";
|
|
463
|
+
import * as Sentry from "@sentry/react-native";
|
|
464
|
+
|
|
465
|
+
class CustomErrorBoundary extends React.Component {
|
|
466
|
+
state = { hasError: false };
|
|
467
|
+
|
|
468
|
+
static getDerivedStateFromError() {
|
|
469
|
+
return { hasError: true };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
componentDidCatch(error: Error, info: React.ErrorInfo) {
|
|
473
|
+
Sentry.captureException(error, {
|
|
474
|
+
extra: { componentStack: info.componentStack },
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
render() {
|
|
479
|
+
if (this.state.hasError) {
|
|
480
|
+
return this.props.fallback ?? null;
|
|
481
|
+
}
|
|
482
|
+
return this.props.children;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
> **Important:** Custom error boundaries **must be class components** — this is a React
|
|
488
|
+
> requirement, not a Sentry limitation.
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## 7. Scope Management
|
|
493
|
+
|
|
494
|
+
Scopes hold contextual data (tags, user, breadcrumbs, contexts) that is merged into
|
|
495
|
+
captured events. There are three scope layers with different lifetimes.
|
|
496
|
+
|
|
497
|
+
### Three Scope Types
|
|
498
|
+
|
|
499
|
+
#### Global Scope
|
|
500
|
+
|
|
501
|
+
Applied to **every event** regardless of origin.
|
|
502
|
+
Used for low-level environmental data.
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
const globalScope = Sentry.getGlobalScope();
|
|
506
|
+
globalScope.setTag("app_type", "mobile");
|
|
507
|
+
globalScope.setContext("runtime", { name: "Hermes", version: "0.11.0" });
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### Isolation Scope
|
|
511
|
+
|
|
512
|
+
Separates events from each other (per-session in mobile).
|
|
513
|
+
All `Sentry.setXXX()` convenience methods write here.
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
// These are equivalent:
|
|
517
|
+
Sentry.setTag("my-tag", "my value");
|
|
518
|
+
Sentry.getIsolationScope().setTag("my-tag", "my value");
|
|
519
|
+
|
|
520
|
+
// Set user for the entire session:
|
|
521
|
+
Sentry.setUser({ id: "42", email: "user@example.com" });
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### Current Scope
|
|
525
|
+
|
|
526
|
+
The locally active scope.
|
|
527
|
+
Best accessed via `withScope()`.
|
|
528
|
+
|
|
529
|
+
### Scope Data Precedence
|
|
530
|
+
|
|
531
|
+
Scopes merge in order: **global → isolation → current**. A key on the current scope
|
|
532
|
+
overrides the same key on outer scopes.
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
Sentry.getGlobalScope().setExtras({ shared: "global", global: "data" });
|
|
536
|
+
Sentry.getIsolationScope().setExtras({ shared: "isolation", isolation: "data" });
|
|
537
|
+
Sentry.getCurrentScope().setExtras({ shared: "current", current: "data" });
|
|
538
|
+
|
|
539
|
+
// Resulting event extras: { shared: "current", global: "data", isolation: "data", current: "data" }
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### `withScope()` — Temporary Isolated Scopes
|
|
543
|
+
|
|
544
|
+
Creates a **cloned scope** valid only inside the callback.
|
|
545
|
+
Changes do not affect the outer scope.
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
// Error 1 gets the tag; Error 2 does NOT
|
|
549
|
+
Sentry.withScope((scope) => {
|
|
550
|
+
scope.setTag("my-tag", "my value");
|
|
551
|
+
scope.setLevel("warning");
|
|
552
|
+
Sentry.captureException(new Error("my error")); // tagged
|
|
553
|
+
});
|
|
554
|
+
Sentry.captureException(new Error("my other error")); // NOT tagged
|
|
555
|
+
|
|
556
|
+
// Temporarily override user identity for one capture
|
|
557
|
+
Sentry.withScope((scope) => {
|
|
558
|
+
scope.setUser({ id: "service-account" });
|
|
559
|
+
Sentry.captureException(backgroundJobError);
|
|
560
|
+
// original user identity restored after this block
|
|
561
|
+
});
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Convenience Methods (All Write to Isolation Scope)
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
Sentry.setTag(key, value);
|
|
568
|
+
Sentry.setTags({ key: value });
|
|
569
|
+
Sentry.setAttribute(key, value); // SDK ≥8.17.2
|
|
570
|
+
Sentry.setAttributes({ key: value }); // SDK ≥8.17.2
|
|
571
|
+
Sentry.setUser({ id, email, username });
|
|
572
|
+
Sentry.setContext(name, object);
|
|
573
|
+
Sentry.setExtra(key, value);
|
|
574
|
+
Sentry.setExtras({ key: value });
|
|
575
|
+
Sentry.addBreadcrumb(breadcrumb);
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## 8. Context Enrichment — Tags, User, Extra, Contexts
|
|
581
|
+
|
|
582
|
+
### Tags — Indexed & Searchable
|
|
583
|
+
|
|
584
|
+
Tags are **key/value string pairs** indexed in Sentry, enabling full-text search, filter
|
|
585
|
+
sidebars, and distribution maps in the UI.
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
Sentry.setTag("page_locale", "de-at");
|
|
589
|
+
Sentry.setTag("app_version", "3.2.1");
|
|
590
|
+
Sentry.setTag("user_plan", "enterprise");
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
**Tag constraints:**
|
|
594
|
+
|
|
595
|
+
| Property | Constraint |
|
|
596
|
+
| ---------------------- | ----------------------------------- |
|
|
597
|
+
| Key max length | 32 characters |
|
|
598
|
+
| Key allowed characters | `a-zA-Z`, `0-9`, `_`, `.`, `:`, `-` |
|
|
599
|
+
| Value max length | 200 characters |
|
|
600
|
+
| Value forbidden | Newline `\n` characters |
|
|
601
|
+
|
|
602
|
+
### User Identity
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
// Set on login
|
|
606
|
+
Sentry.setUser({
|
|
607
|
+
id: "42",
|
|
608
|
+
email: "john.doe@example.com",
|
|
609
|
+
username: "johndoe",
|
|
610
|
+
ip_address: "{{auto}}", // Sentry resolves this automatically
|
|
611
|
+
// Any additional key-value pairs
|
|
612
|
+
plan: "enterprise",
|
|
613
|
+
role: "admin",
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
// Clear on logout
|
|
617
|
+
Sentry.setUser(null);
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Custom Structured Contexts
|
|
621
|
+
|
|
622
|
+
Structured contexts attach arbitrary nested objects to events.
|
|
623
|
+
They appear on the issue detail page but are **not searchable** (use tags for searchable
|
|
624
|
+
data).
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
Sentry.setContext("character", {
|
|
628
|
+
name: "Mighty Fighter",
|
|
629
|
+
age: 19,
|
|
630
|
+
attack_type: "melee",
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
Sentry.setContext("order", {
|
|
634
|
+
id: "ORD-9821",
|
|
635
|
+
total: 129.99,
|
|
636
|
+
items: ["item-1", "item-2"],
|
|
637
|
+
shipping: { method: "express", address: "123 Main St" },
|
|
638
|
+
});
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
> **Notes:**
|
|
642
|
+
>
|
|
643
|
+
> - The key `"type"` is reserved by Sentry — do not use it
|
|
644
|
+
> - Context nesting is normalized to **3 levels** by default (configurable via
|
|
645
|
+
> `normalizeDepth`)
|
|
646
|
+
> - Avoid sending entire app state blobs; exceeding max payload size triggers HTTP `413`
|
|
647
|
+
|
|
648
|
+
### Extra Data (Deprecated)
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
// Deprecated — use setContext() instead
|
|
652
|
+
Sentry.setExtra("server_name", "web-01");
|
|
653
|
+
Sentry.setExtras({ key1: "value1", key2: "value2" });
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Inline Context on Capture Calls
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
Sentry.captureException(new Error("something went wrong"), {
|
|
660
|
+
tags: { section: "articles" },
|
|
661
|
+
user: { id: "42", email: "user@example.com" },
|
|
662
|
+
extra: { requestId: "abc-123" },
|
|
663
|
+
contexts: { order: { id: "ORD-9821" } },
|
|
664
|
+
level: "warning",
|
|
665
|
+
fingerprint: ["{{ default }}", "order-error"],
|
|
666
|
+
});
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Clearing Context
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
// Clear all scope data
|
|
673
|
+
Sentry.getCurrentScope().clear();
|
|
674
|
+
|
|
675
|
+
// Reset user
|
|
676
|
+
Sentry.setUser(null);
|
|
677
|
+
|
|
678
|
+
// Remove a specific tag
|
|
679
|
+
Sentry.setTag("key", undefined);
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## 9. Breadcrumbs — Automatic & Manual
|
|
685
|
+
|
|
686
|
+
Breadcrumbs form a timeline of events leading up to an error.
|
|
687
|
+
They buffer until the next event is captured — they do not create Sentry issues on their
|
|
688
|
+
own.
|
|
689
|
+
|
|
690
|
+
### Manual Breadcrumbs
|
|
691
|
+
|
|
692
|
+
```typescript
|
|
693
|
+
import * as Sentry from "@sentry/react-native";
|
|
694
|
+
|
|
695
|
+
// Navigation event
|
|
696
|
+
Sentry.addBreadcrumb({
|
|
697
|
+
category: "navigation",
|
|
698
|
+
message: "Navigated to screen",
|
|
699
|
+
level: "info",
|
|
700
|
+
data: {
|
|
701
|
+
from: "HomeScreen",
|
|
702
|
+
to: "ProfileScreen",
|
|
703
|
+
params: { userId: "42" },
|
|
704
|
+
},
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// Authentication event
|
|
708
|
+
Sentry.addBreadcrumb({
|
|
709
|
+
category: "auth",
|
|
710
|
+
message: "User logged in: " + user.email,
|
|
711
|
+
level: "info",
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
// API failure before throwing
|
|
715
|
+
Sentry.addBreadcrumb({
|
|
716
|
+
category: "api",
|
|
717
|
+
message: "Checkout API call failed",
|
|
718
|
+
level: "error",
|
|
719
|
+
data: {
|
|
720
|
+
url: "/api/checkout",
|
|
721
|
+
status: 500,
|
|
722
|
+
method: "POST",
|
|
723
|
+
},
|
|
724
|
+
});
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
**Breadcrumb properties:**
|
|
728
|
+
|
|
729
|
+
| Property | Description |
|
|
730
|
+
| ----------- | ----------------------------------------------------------------------------- |
|
|
731
|
+
| `type` | `"default"`, `"http"`, `"navigation"`, `"user"` |
|
|
732
|
+
| `category` | Dot-separated string (e.g., `"ui.click"`, `"http"`, `"auth"`) |
|
|
733
|
+
| `message` | Human-readable description |
|
|
734
|
+
| `level` | `"fatal"`, `"critical"`, `"error"`, `"warning"`, `"log"`, `"info"`, `"debug"` |
|
|
735
|
+
| `timestamp` | Unix timestamp (auto-set if omitted) |
|
|
736
|
+
| `data` | Arbitrary `{ key: value }` metadata |
|
|
737
|
+
|
|
738
|
+
> **Warning:** Unknown keys beyond those above are silently dropped during processing.
|
|
739
|
+
|
|
740
|
+
### Automatic Breadcrumbs
|
|
741
|
+
|
|
742
|
+
| Source | Category | How |
|
|
743
|
+
| ------------------ | -------------- | --------------------------------------------------------- |
|
|
744
|
+
| Touch interactions | `ui.click` | Via `Sentry.wrap` on root component |
|
|
745
|
+
| HTTP requests | `http` | Fetch/XHR patching (default) |
|
|
746
|
+
| Console output | `console` | `console.log/warn/error` patching (default) |
|
|
747
|
+
| Navigation | `navigation` | Via navigation integrations |
|
|
748
|
+
| Redux actions | `redux.action` | Via `Sentry.createReduxEnhancer` |
|
|
749
|
+
| Native lifecycle | various | From native SDKs (connectivity changes, lifecycle events) |
|
|
750
|
+
|
|
751
|
+
### `beforeBreadcrumb` Hook
|
|
752
|
+
|
|
753
|
+
```typescript
|
|
754
|
+
Sentry.init({
|
|
755
|
+
beforeBreadcrumb(breadcrumb, hint) {
|
|
756
|
+
// Drop all UI click breadcrumbs
|
|
757
|
+
if (breadcrumb.category === "ui.click") {
|
|
758
|
+
return null;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// Scrub auth tokens from HTTP breadcrumbs
|
|
762
|
+
if (breadcrumb.category === "http" && breadcrumb.data?.url) {
|
|
763
|
+
breadcrumb.data.url = breadcrumb.data.url.replace(/token=[^&]*/, "token=REDACTED");
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// Add extra metadata to console breadcrumbs
|
|
767
|
+
if (breadcrumb.category === "console") {
|
|
768
|
+
breadcrumb.data = { ...breadcrumb.data, deviceTime: Date.now() };
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
return breadcrumb; // return null to drop
|
|
772
|
+
},
|
|
773
|
+
});
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
### Breadcrumb Capacity
|
|
777
|
+
|
|
778
|
+
```typescript
|
|
779
|
+
Sentry.init({
|
|
780
|
+
// Default is 100; oldest breadcrumbs are discarded when full
|
|
781
|
+
maxBreadcrumbs: 50,
|
|
782
|
+
});
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
---
|
|
786
|
+
|
|
787
|
+
## 10. `beforeSend` / `beforeSendTransaction` Hooks
|
|
788
|
+
|
|
789
|
+
These hooks fire immediately before an event is transmitted, giving you a final chance
|
|
790
|
+
to modify or suppress it.
|
|
791
|
+
|
|
792
|
+
> **Important:** `beforeSend` only runs on **JavaScript-layer events**. It does not
|
|
793
|
+
> affect native Android/iOS crash events captured by the native SDKs.
|
|
794
|
+
|
|
795
|
+
### `beforeSend` — Error Events
|
|
796
|
+
|
|
797
|
+
```typescript
|
|
798
|
+
Sentry.init({
|
|
799
|
+
beforeSend(event, hint) {
|
|
800
|
+
// hint.originalException — the original thrown Error object
|
|
801
|
+
// hint.syntheticException — auto-generated when non-Error is thrown
|
|
802
|
+
// hint.event_id — the generated event ID
|
|
803
|
+
|
|
804
|
+
// Drop events matching a pattern
|
|
805
|
+
if (event.exception?.values?.[0]?.value?.includes("ResizeObserver")) {
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// Scrub PII before sending
|
|
810
|
+
if (event.user) {
|
|
811
|
+
delete event.user.email;
|
|
812
|
+
delete event.user.ip_address;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// Set fingerprint based on error message
|
|
816
|
+
const error = hint.originalException as Error;
|
|
817
|
+
if (error?.message?.match(/database unavailable/i)) {
|
|
818
|
+
event.fingerprint = ["database-unavailable"];
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// Attach extra data
|
|
822
|
+
event.extra = {
|
|
823
|
+
...event.extra,
|
|
824
|
+
build_number: "42",
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
return event; // return null to drop, return event to send
|
|
828
|
+
},
|
|
829
|
+
});
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
### `beforeSendTransaction` — Performance Transactions
|
|
833
|
+
|
|
834
|
+
```typescript
|
|
835
|
+
Sentry.init({
|
|
836
|
+
beforeSendTransaction(event) {
|
|
837
|
+
// Drop health check transactions
|
|
838
|
+
if (event.transaction === "/health") return null;
|
|
839
|
+
|
|
840
|
+
// Normalize internal transaction names
|
|
841
|
+
if (event.transaction?.startsWith("/internal/")) {
|
|
842
|
+
event.transaction = "/internal/*";
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
return event;
|
|
846
|
+
},
|
|
847
|
+
});
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### `ignoreErrors` / `ignoreTransactions`
|
|
851
|
+
|
|
852
|
+
Pre-filter before `beforeSend` even runs — more efficient for known noise patterns:
|
|
853
|
+
|
|
854
|
+
```typescript
|
|
855
|
+
Sentry.init({
|
|
856
|
+
ignoreErrors: [
|
|
857
|
+
"ResizeObserver loop limit exceeded",
|
|
858
|
+
"Non-Error exception captured",
|
|
859
|
+
/^Script error\.?$/,
|
|
860
|
+
],
|
|
861
|
+
ignoreTransactions: ["/healthcheck", /^\/admin\/internal\//],
|
|
862
|
+
});
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
---
|
|
866
|
+
|
|
867
|
+
## 11. Fingerprinting & Grouping
|
|
868
|
+
|
|
869
|
+
Fingerprinting controls how Sentry groups events into issues.
|
|
870
|
+
By default, Sentry groups by stack trace.
|
|
871
|
+
You can override this to merge or split issues.
|
|
872
|
+
|
|
873
|
+
### SDK-Level Fingerprinting
|
|
874
|
+
|
|
875
|
+
```typescript
|
|
876
|
+
// Static fingerprint — all matching events become one issue
|
|
877
|
+
Sentry.captureException(new Error("DB connection failed"), {
|
|
878
|
+
fingerprint: ["database-connection-error"],
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
// Dynamic — include URL and status for more granular groups
|
|
882
|
+
Sentry.captureException(networkErr, {
|
|
883
|
+
fingerprint: ["{{ default }}", networkErr.url, String(networkErr.status)],
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
// Dynamic via beforeSend
|
|
887
|
+
Sentry.init({
|
|
888
|
+
beforeSend(event, hint) {
|
|
889
|
+
const error = hint.originalException as Error;
|
|
890
|
+
if (error?.message?.match(/network request failed/i)) {
|
|
891
|
+
event.fingerprint = ["network-error", event.request?.url ?? "unknown-url"];
|
|
892
|
+
}
|
|
893
|
+
return event;
|
|
894
|
+
},
|
|
895
|
+
});
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### Fingerprint Variables
|
|
899
|
+
|
|
900
|
+
| Variable | Resolves to |
|
|
901
|
+
| ---------------------- | ------------------------------ |
|
|
902
|
+
| `{{ default }}` | Sentry’s default grouping hash |
|
|
903
|
+
| `{{ error.type }}` | Exception class name |
|
|
904
|
+
| `{{ error.value }}` | Exception message text |
|
|
905
|
+
| `{{ transaction }}` | Current transaction name |
|
|
906
|
+
| `{{ level }}` | Event severity level |
|
|
907
|
+
| `{{ message }}` | Captured message |
|
|
908
|
+
| `{{ stack.function }}` | Top stack frame function name |
|
|
909
|
+
| `{{ stack.module }}` | Top stack frame module |
|
|
910
|
+
|
|
911
|
+
### Server-Side Fingerprint Rules (Project Settings)
|
|
912
|
+
|
|
913
|
+
```
|
|
914
|
+
# Group all DB errors together regardless of message
|
|
915
|
+
error.type:DatabaseUnavailable -> system-down
|
|
916
|
+
error.type:ConnectionError -> system-down
|
|
917
|
+
|
|
918
|
+
# Subdivide connection errors by transaction
|
|
919
|
+
error.value:"connection error: *" -> connection-error, {{ transaction }}
|
|
920
|
+
|
|
921
|
+
# Custom issue title
|
|
922
|
+
logger:my.package.* level:error -> error-logger, {{ logger }} title="Error from Logger {{ logger }}"
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
### Fingerprint Priority
|
|
926
|
+
|
|
927
|
+
1. SDK-set `fingerprint` (in `captureException`, `beforeSend`, or `captureEvent`)
|
|
928
|
+
2. Server-side fingerprint rules (Sentry project settings)
|
|
929
|
+
3. Sentry’s default stack-trace-based grouping
|
|
930
|
+
|
|
931
|
+
---
|
|
932
|
+
|
|
933
|
+
## 12. Event Processors
|
|
934
|
+
|
|
935
|
+
Event processors run on **every event** before transmission.
|
|
936
|
+
They differ from `beforeSend` in two key ways:
|
|
937
|
+
|
|
938
|
+
1. `beforeSend` always runs **last**, after all event processors
|
|
939
|
+
2. Processors added to a scope only apply to events **within that scope**
|
|
940
|
+
|
|
941
|
+
### Global Event Processor
|
|
942
|
+
|
|
943
|
+
```typescript
|
|
944
|
+
import * as Sentry from "@sentry/react-native";
|
|
945
|
+
|
|
946
|
+
Sentry.addEventProcessor((event, hint) => {
|
|
947
|
+
// Enrich all events with app metadata
|
|
948
|
+
event.extra = {
|
|
949
|
+
...event.extra,
|
|
950
|
+
appBuildTime: BUILD_TIMESTAMP,
|
|
951
|
+
featureFlags: getActiveFeatureFlags(),
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
// Drop events from test environments
|
|
955
|
+
if (isTestEnvironment()) return null;
|
|
956
|
+
|
|
957
|
+
return event;
|
|
958
|
+
});
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### Scoped Event Processor
|
|
962
|
+
|
|
963
|
+
```typescript
|
|
964
|
+
Sentry.withScope((scope) => {
|
|
965
|
+
scope.addEventProcessor((event, hint) => {
|
|
966
|
+
// Only runs for events captured inside this withScope block
|
|
967
|
+
event.tags = { ...event.tags, flow: "checkout" };
|
|
968
|
+
return event;
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
Sentry.captureException(checkoutError); // ✅ processor fires
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
Sentry.captureException(otherError); // ❌ processor does NOT fire
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
### Async Event Processors
|
|
978
|
+
|
|
979
|
+
```typescript
|
|
980
|
+
Sentry.addEventProcessor(async (event, hint) => {
|
|
981
|
+
const deviceInfo = await getDeviceInfo();
|
|
982
|
+
event.contexts = { ...event.contexts, device: deviceInfo };
|
|
983
|
+
return event;
|
|
984
|
+
});
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
### Execution Order
|
|
988
|
+
|
|
989
|
+
```
|
|
990
|
+
[All addEventProcessor / scope.addEventProcessor functions]
|
|
991
|
+
↓ (in registration order)
|
|
992
|
+
[beforeSend / beforeSendTransaction]
|
|
993
|
+
↓ (always last)
|
|
994
|
+
[Sentry servers]
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
---
|
|
998
|
+
|
|
999
|
+
## 13. Attachments — Screenshots & View Hierarchy
|
|
1000
|
+
|
|
1001
|
+
### Automatic Screenshot on Error
|
|
1002
|
+
|
|
1003
|
+
Captures a PNG screenshot at the moment an error occurs.
|
|
1004
|
+
Attached to the event in Sentry’s issue detail view.
|
|
1005
|
+
|
|
1006
|
+
```typescript
|
|
1007
|
+
Sentry.init({
|
|
1008
|
+
// Available since @sentry/react-native v4.11.0
|
|
1009
|
+
attachScreenshot: true,
|
|
1010
|
+
});
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
Screenshots appear under **“Attachments”** on the event detail page in Sentry.
|
|
1014
|
+
|
|
1015
|
+
> **PII consideration:** Screenshots may capture sensitive data visible on screen
|
|
1016
|
+
> (forms, personal information).
|
|
1017
|
+
> Review before enabling in production.
|
|
1018
|
+
|
|
1019
|
+
### View Hierarchy Capture
|
|
1020
|
+
|
|
1021
|
+
Captures a JSON representation of the native component hierarchy at crash time.
|
|
1022
|
+
|
|
1023
|
+
```typescript
|
|
1024
|
+
Sentry.init({
|
|
1025
|
+
attachViewHierarchy: true,
|
|
1026
|
+
});
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
The view hierarchy appears in Sentry’s **“View Hierarchy”** tab on the event.
|
|
1030
|
+
|
|
1031
|
+
### Manual File Attachments
|
|
1032
|
+
|
|
1033
|
+
```typescript
|
|
1034
|
+
Sentry.captureException(err, {
|
|
1035
|
+
attachments: [
|
|
1036
|
+
{
|
|
1037
|
+
filename: "config.json",
|
|
1038
|
+
data: JSON.stringify(appConfig),
|
|
1039
|
+
contentType: "application/json",
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
filename: "debug.log",
|
|
1043
|
+
data: logFileContents, // string or Uint8Array
|
|
1044
|
+
contentType: "text/plain",
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
filename: "screenshot.png",
|
|
1048
|
+
data: base64PngData,
|
|
1049
|
+
contentType: "image/png",
|
|
1050
|
+
},
|
|
1051
|
+
],
|
|
1052
|
+
});
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
### Attachments via Scope
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
Sentry.withScope((scope) => {
|
|
1059
|
+
scope.addAttachment({
|
|
1060
|
+
filename: "state_snapshot.json",
|
|
1061
|
+
data: JSON.stringify(store.getState()),
|
|
1062
|
+
contentType: "application/json",
|
|
1063
|
+
});
|
|
1064
|
+
Sentry.captureException(error);
|
|
1065
|
+
});
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
> **Size limits:** Attachments must not push the total event payload over Sentry’s
|
|
1069
|
+
> maximum. Oversized payloads return HTTP `413 Payload Too Large`.
|
|
1070
|
+
|
|
1071
|
+
---
|
|
1072
|
+
|
|
1073
|
+
## 14. Redux Integration
|
|
1074
|
+
|
|
1075
|
+
The `createReduxEnhancer` captures Redux state snapshots and action history as
|
|
1076
|
+
breadcrumbs on error events.
|
|
1077
|
+
|
|
1078
|
+
### Setup
|
|
1079
|
+
|
|
1080
|
+
```typescript
|
|
1081
|
+
import { createStore } from "redux";
|
|
1082
|
+
import * as Sentry from "@sentry/react-native";
|
|
1083
|
+
|
|
1084
|
+
const store = createStore(
|
|
1085
|
+
rootReducer,
|
|
1086
|
+
Sentry.createReduxEnhancer({
|
|
1087
|
+
// Transform action before recording — return null to skip
|
|
1088
|
+
actionTransformer: (action) => {
|
|
1089
|
+
if (action.type === "SENSITIVE_ACTION") return null;
|
|
1090
|
+
if (action.type === "SET_PASSWORD") {
|
|
1091
|
+
return { ...action, payload: "[REDACTED]" };
|
|
1092
|
+
}
|
|
1093
|
+
return action;
|
|
1094
|
+
},
|
|
1095
|
+
|
|
1096
|
+
// Transform state snapshot — avoid sending large state trees
|
|
1097
|
+
stateTransformer: (state) => ({
|
|
1098
|
+
selectedTab: state.ui.selectedTab,
|
|
1099
|
+
userPlan: state.user.plan,
|
|
1100
|
+
cartItemCount: state.cart.items.length,
|
|
1101
|
+
}),
|
|
1102
|
+
}),
|
|
1103
|
+
);
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
### With Redux Toolkit
|
|
1107
|
+
|
|
1108
|
+
```typescript
|
|
1109
|
+
import { configureStore } from "@reduxjs/toolkit";
|
|
1110
|
+
import * as Sentry from "@sentry/react-native";
|
|
1111
|
+
|
|
1112
|
+
const store = configureStore({
|
|
1113
|
+
reducer: rootReducer,
|
|
1114
|
+
enhancers: (getDefaultEnhancers) =>
|
|
1115
|
+
getDefaultEnhancers().concat(
|
|
1116
|
+
Sentry.createReduxEnhancer({
|
|
1117
|
+
actionTransformer: (action) => {
|
|
1118
|
+
// Drop auth-related actions from breadcrumbs
|
|
1119
|
+
if (action.type.startsWith("auth/")) return null;
|
|
1120
|
+
return action;
|
|
1121
|
+
},
|
|
1122
|
+
}),
|
|
1123
|
+
),
|
|
1124
|
+
});
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
Dispatched actions appear in Sentry as `redux.action` breadcrumbs.
|
|
1128
|
+
State at the time of an error is attached to the event under `state.value`.
|
|
1129
|
+
|
|
1130
|
+
---
|
|
1131
|
+
|
|
1132
|
+
## 15. Device & App Context
|
|
1133
|
+
|
|
1134
|
+
The SDK automatically attaches rich device context to every event — no configuration
|
|
1135
|
+
required.
|
|
1136
|
+
|
|
1137
|
+
### Automatic Context (No Setup Needed)
|
|
1138
|
+
|
|
1139
|
+
| Context Section | Fields | Source |
|
|
1140
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------ | -------------------------------------- |
|
|
1141
|
+
| **Device** | Model, manufacturer, brand, screen resolution, orientation, free memory, battery level, charging state | Native SDK |
|
|
1142
|
+
| **OS** | Name (`iOS`/`Android`), version, build number, kernel version | Native SDK |
|
|
1143
|
+
| **App** | App ID, version name, version code, build type | Native SDK |
|
|
1144
|
+
| **React Native** | RN version, JS engine (Hermes/JSC), architecture | JS SDK |
|
|
1145
|
+
| **Expo Constants** | Execution environment, app name/slug/version, Expo SDK version, EAS project ID, session ID, debug mode | `expoConstantsIntegration` (Expo only) |
|
|
1146
|
+
|
|
1147
|
+
These appear in Sentry under the **“Device”**, **“Operating System”**, **“App”**, and
|
|
1148
|
+
(for Expo apps) **“expo_constants”** sections of any event.
|
|
1149
|
+
|
|
1150
|
+
### Expo Constants Context
|
|
1151
|
+
|
|
1152
|
+
When running in an Expo app, the `expoConstantsIntegration` is enabled automatically and
|
|
1153
|
+
attaches an `expo_constants` context to every event.
|
|
1154
|
+
No configuration is required.
|
|
1155
|
+
|
|
1156
|
+
The context includes the following fields (only non-empty values are set):
|
|
1157
|
+
|
|
1158
|
+
| Field | Type | Source |
|
|
1159
|
+
| ----------------------- | --------- | -------------------------------------------- |
|
|
1160
|
+
| `execution_environment` | `string` | `'bare'`, `'standalone'`, or `'storeClient'` |
|
|
1161
|
+
| `app_ownership` | `string` | `'expo'` in Expo Go, otherwise absent |
|
|
1162
|
+
| `debug_mode` | `boolean` | Whether the app is in debug mode |
|
|
1163
|
+
| `expo_version` | `string` | Expo Go client version |
|
|
1164
|
+
| `expo_runtime_version` | `string` | EAS Update runtime version |
|
|
1165
|
+
| `session_id` | `string` | Unique per app session |
|
|
1166
|
+
| `status_bar_height` | `number` | Device status bar height in points |
|
|
1167
|
+
| `app_name` | `string` | `expoConfig.name` from `app.json` |
|
|
1168
|
+
| `app_slug` | `string` | `expoConfig.slug` from `app.json` |
|
|
1169
|
+
| `app_version` | `string` | `expoConfig.version` from `app.json` |
|
|
1170
|
+
| `expo_sdk_version` | `string` | Expo SDK version from `app.json` |
|
|
1171
|
+
| `eas_project_id` | `string` | EAS project ID from `easConfig.projectId` |
|
|
1172
|
+
|
|
1173
|
+
To view the context in Sentry, open any event from an Expo app and look for the
|
|
1174
|
+
`expo_constants` section in the event detail page.
|
|
1175
|
+
|
|
1176
|
+
### Overriding or Extending Device Context
|
|
1177
|
+
|
|
1178
|
+
```typescript
|
|
1179
|
+
Sentry.setContext("device", {
|
|
1180
|
+
custom_hardware_id: "DEVICE-UUID-123",
|
|
1181
|
+
});
|
|
1182
|
+
|
|
1183
|
+
Sentry.setContext("app", {
|
|
1184
|
+
app_version: "3.2.1",
|
|
1185
|
+
app_build: "421",
|
|
1186
|
+
custom_build_flavor: "staging",
|
|
1187
|
+
});
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
### Release, Distribution & Environment
|
|
1191
|
+
|
|
1192
|
+
```typescript
|
|
1193
|
+
Sentry.init({
|
|
1194
|
+
// Used in Sentry for regression detection and release health
|
|
1195
|
+
release: "com.myapp@3.2.1+421",
|
|
1196
|
+
|
|
1197
|
+
// Distinguishes builds within a release (e.g., Xcode build number)
|
|
1198
|
+
dist: "421",
|
|
1199
|
+
|
|
1200
|
+
// Shown on every event for filtering
|
|
1201
|
+
environment: "production", // "staging" | "development" | "production"
|
|
1202
|
+
});
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
---
|
|
1206
|
+
|
|
1207
|
+
## 16. Release Health & Sessions
|
|
1208
|
+
|
|
1209
|
+
Sentry tracks **session-based metrics** to surface crash-free rates and regressions
|
|
1210
|
+
across app versions.
|
|
1211
|
+
|
|
1212
|
+
### How Sessions Work
|
|
1213
|
+
|
|
1214
|
+
A session begins when the app comes to the foreground and ends when it goes to
|
|
1215
|
+
background for longer than `sessionTrackingIntervalMillis` (default: 30 seconds).
|
|
1216
|
+
Each session maps to a release version, enabling Sentry to compute:
|
|
1217
|
+
|
|
1218
|
+
- **Crash-free session rate** — % of sessions without a fatal crash
|
|
1219
|
+
- **Crash-free user rate** — % of users without a crash in a given release
|
|
1220
|
+
|
|
1221
|
+
```typescript
|
|
1222
|
+
Sentry.init({
|
|
1223
|
+
release: "com.myapp@3.2.1+421",
|
|
1224
|
+
autoSessionTracking: true, // default: true
|
|
1225
|
+
sessionTrackingIntervalMillis: 30000, // default: 30s background threshold
|
|
1226
|
+
});
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
Sessions are sent automatically.
|
|
1230
|
+
No additional API calls are required.
|
|
1231
|
+
|
|
1232
|
+
---
|
|
1233
|
+
|
|
1234
|
+
## 17. Offline Event Caching
|
|
1235
|
+
|
|
1236
|
+
The SDK caches events locally when the device has no network connectivity.
|
|
1237
|
+
Events are transmitted automatically when connectivity is restored.
|
|
1238
|
+
|
|
1239
|
+
```typescript
|
|
1240
|
+
Sentry.init({
|
|
1241
|
+
// Maximum number of envelopes to cache on disk (default: 30)
|
|
1242
|
+
maxCacheItems: 30,
|
|
1243
|
+
});
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
| Platform | Cache Location | Transmission Trigger |
|
|
1247
|
+
| -------- | ----------------------------- | -------------------- |
|
|
1248
|
+
| Android | Internal app storage | App restart |
|
|
1249
|
+
| iOS | App sandbox `Library/Caches/` | Next event fires |
|
|
1250
|
+
|
|
1251
|
+
Offline caching works for both JS-layer events and native crash reports.
|
|
1252
|
+
|
|
1253
|
+
---
|
|
1254
|
+
|
|
1255
|
+
## 18. Default Integrations
|
|
1256
|
+
|
|
1257
|
+
The following integrations are enabled automatically:
|
|
1258
|
+
|
|
1259
|
+
| Integration | Purpose |
|
|
1260
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1261
|
+
| **InboundFilters** | Drops events matching `ignoreErrors`, `denyUrls`, `allowUrls`. Default-ignores `"Script error"` |
|
|
1262
|
+
| **FunctionToString** | Preserves original function names even when SDK wraps handlers |
|
|
1263
|
+
| **Breadcrumbs** | Patches `console`, `fetch`, `XHR` to auto-capture breadcrumbs |
|
|
1264
|
+
| **NativeLinkedErrors** | Reads `.cause` chains up to 5 levels deep |
|
|
1265
|
+
| **HttpContext** | Attaches URL, user-agent, referrer to events |
|
|
1266
|
+
| **Dedupe** | Prevents duplicate consecutive events from being reported |
|
|
1267
|
+
| **UnhandledRejection** | Auto-captures unhandled promise rejections |
|
|
1268
|
+
| **ExpoConstants** | Attaches `expo_constants` context (execution environment, app name, EAS project ID, etc.) to every event. Active only when running in an Expo app |
|
|
1269
|
+
|
|
1270
|
+
### Customizing Default Integrations
|
|
1271
|
+
|
|
1272
|
+
```typescript
|
|
1273
|
+
// Disable all defaults (rarely needed)
|
|
1274
|
+
Sentry.init({ defaultIntegrations: false });
|
|
1275
|
+
|
|
1276
|
+
// Disable console breadcrumbs only
|
|
1277
|
+
Sentry.init({
|
|
1278
|
+
integrations: [
|
|
1279
|
+
Sentry.breadcrumbsIntegration({
|
|
1280
|
+
console: false, // disable console breadcrumbs
|
|
1281
|
+
fetch: true,
|
|
1282
|
+
xhr: true,
|
|
1283
|
+
sentry: true,
|
|
1284
|
+
// Note: `dom` and `history` are web-only — not applicable in React Native
|
|
1285
|
+
}),
|
|
1286
|
+
],
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
// Remove a specific integration
|
|
1290
|
+
Sentry.init({
|
|
1291
|
+
integrations: (integrations) => integrations.filter((i) => i.name !== "Breadcrumbs"),
|
|
1292
|
+
});
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
### Opt-In Integrations
|
|
1296
|
+
|
|
1297
|
+
```typescript
|
|
1298
|
+
Sentry.init({
|
|
1299
|
+
integrations: [
|
|
1300
|
+
// Capture failed HTTP requests (non-2xx) as Sentry errors (v5.3.0+)
|
|
1301
|
+
Sentry.httpClientIntegration({
|
|
1302
|
+
failedRequestStatusCodes: [[400, 599]],
|
|
1303
|
+
failedRequestTargets: ["https://api.myapp.com"],
|
|
1304
|
+
}),
|
|
1305
|
+
|
|
1306
|
+
// Rewrite stack frame file paths (useful for custom source map layouts)
|
|
1307
|
+
Sentry.rewriteFramesIntegration({ root: "/" }),
|
|
1308
|
+
],
|
|
1309
|
+
// Shorthand for httpClientIntegration with default settings:
|
|
1310
|
+
enableCaptureFailedRequests: true,
|
|
1311
|
+
});
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
---
|
|
1315
|
+
|
|
1316
|
+
## 19. Full `init()` Options Reference
|
|
1317
|
+
|
|
1318
|
+
```typescript
|
|
1319
|
+
import * as Sentry from "@sentry/react-native";
|
|
1320
|
+
|
|
1321
|
+
Sentry.init({
|
|
1322
|
+
// ── Core ──────────────────────────────────────────────────────────
|
|
1323
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1324
|
+
enabled: true, // false disables all SDK transmission
|
|
1325
|
+
debug: false, // log SDK internals to console
|
|
1326
|
+
release: "com.myapp@3.2.1+421",
|
|
1327
|
+
dist: "421", // distinguishes builds within a release
|
|
1328
|
+
environment: "production",
|
|
1329
|
+
sampleRate: 1.0, // 0.0–1.0; fraction of error events to send
|
|
1330
|
+
|
|
1331
|
+
// ── Filtering ─────────────────────────────────────────────────────
|
|
1332
|
+
ignoreErrors: ["Script error", /^Non-Error/],
|
|
1333
|
+
ignoreTransactions: ["/healthcheck"],
|
|
1334
|
+
// denyUrls / allowUrls match stack frame URLs — primarily useful for web;
|
|
1335
|
+
// in React Native these can filter native frames but are rarely needed.
|
|
1336
|
+
// denyUrls: ["chrome-extension://", /extensions\//i],
|
|
1337
|
+
// allowUrls: ["https://myapp.com"],
|
|
1338
|
+
maxBreadcrumbs: 100,
|
|
1339
|
+
maxValueLength: 250, // max length of string values in events
|
|
1340
|
+
|
|
1341
|
+
// ── Normalization ─────────────────────────────────────────────────
|
|
1342
|
+
normalizeDepth: 3, // depth to normalize context objects
|
|
1343
|
+
normalizeMaxBreadth: 1000, // max number of object properties
|
|
1344
|
+
|
|
1345
|
+
// ── Hooks ─────────────────────────────────────────────────────────
|
|
1346
|
+
beforeSend(event, hint) {
|
|
1347
|
+
// JS-layer events only. Return null to drop.
|
|
1348
|
+
return event;
|
|
1349
|
+
},
|
|
1350
|
+
beforeSendTransaction(event) {
|
|
1351
|
+
return event;
|
|
1352
|
+
},
|
|
1353
|
+
beforeBreadcrumb(breadcrumb, hint) {
|
|
1354
|
+
return breadcrumb; // return null to drop
|
|
1355
|
+
},
|
|
1356
|
+
|
|
1357
|
+
// ── Attachments ───────────────────────────────────────────────────
|
|
1358
|
+
attachStacktrace: true, // stack traces on captureMessage calls
|
|
1359
|
+
attachScreenshot: false, // auto-screenshot on error (v4.11.0+)
|
|
1360
|
+
attachViewHierarchy: false, // native view hierarchy JSON on error
|
|
1361
|
+
sendDefaultPii: false, // allow integrations to send PII
|
|
1362
|
+
|
|
1363
|
+
// ── Transport ─────────────────────────────────────────────────────
|
|
1364
|
+
maxCacheItems: 30, // max envelopes cached offline
|
|
1365
|
+
shutdownTimeout: 2000, // ms to wait for queue drain on shutdown
|
|
1366
|
+
|
|
1367
|
+
// ── Sessions ──────────────────────────────────────────────────────
|
|
1368
|
+
autoSessionTracking: true,
|
|
1369
|
+
sessionTrackingIntervalMillis: 30000,
|
|
1370
|
+
|
|
1371
|
+
// ── Performance / Tracing ─────────────────────────────────────────
|
|
1372
|
+
tracesSampleRate: 0.2,
|
|
1373
|
+
tracesSampler: ({ name, attributes, parentSampled }) => {
|
|
1374
|
+
if (name.includes("healthcheck")) return 0;
|
|
1375
|
+
if (typeof parentSampled === "boolean") return parentSampled;
|
|
1376
|
+
return 0.2;
|
|
1377
|
+
},
|
|
1378
|
+
tracePropagationTargets: ["localhost", /^https:\/\/api\.myapp\.com/],
|
|
1379
|
+
enableAutoPerformanceTracing: true,
|
|
1380
|
+
|
|
1381
|
+
// ── Native / Hybrid ───────────────────────────────────────────────
|
|
1382
|
+
enableNative: true,
|
|
1383
|
+
enableNativeCrashHandling: true,
|
|
1384
|
+
autoInitializeNativeSdk: true,
|
|
1385
|
+
enableNdkScopeSync: true, // sync Java scope to NDK (Android)
|
|
1386
|
+
enableTombstone: true, // Android 12+ ApplicationExitInfo (default: false)
|
|
1387
|
+
attachThreads: false, // all threads on Android events
|
|
1388
|
+
enableNativeNagger: true, // warn if native init fails
|
|
1389
|
+
enableWatchdogTerminationTracking: true, // iOS OOM tracking
|
|
1390
|
+
|
|
1391
|
+
// ── ANR / App Hang ────────────────────────────────────────────────
|
|
1392
|
+
enableAppHangTracking: true, // Apple platforms only
|
|
1393
|
+
appHangTimeoutInterval: 2, // Apple platforms only, seconds
|
|
1394
|
+
|
|
1395
|
+
// ── HTTP Client ───────────────────────────────────────────────────
|
|
1396
|
+
enableCaptureFailedRequests: false, // auto-capture HTTP errors (v5.3.0+)
|
|
1397
|
+
|
|
1398
|
+
// ── Callbacks ─────────────────────────────────────────────────────
|
|
1399
|
+
onReady: () => console.log("Sentry native SDKs initialized"),
|
|
1400
|
+
onNativeLog: ({ level, component, message }) => {
|
|
1401
|
+
// Forward native SDK logs to JS console (debug: true required)
|
|
1402
|
+
// Use consoleSandbox to prevent breadcrumb feedback loops
|
|
1403
|
+
},
|
|
1404
|
+
|
|
1405
|
+
// ── Integrations ──────────────────────────────────────────────────
|
|
1406
|
+
integrations: [
|
|
1407
|
+
Sentry.feedbackIntegration({
|
|
1408
|
+
styles: { submitButton: { backgroundColor: "#6a1b9a" } },
|
|
1409
|
+
}),
|
|
1410
|
+
Sentry.httpClientIntegration(),
|
|
1411
|
+
],
|
|
1412
|
+
defaultIntegrations: true, // false disables all built-in integrations
|
|
1413
|
+
});
|
|
1414
|
+
```
|
|
1415
|
+
|
|
1416
|
+
---
|
|
1417
|
+
|
|
1418
|
+
## 20. Quick Reference Cheatsheet
|
|
1419
|
+
|
|
1420
|
+
```typescript
|
|
1421
|
+
import * as Sentry from "@sentry/react-native";
|
|
1422
|
+
|
|
1423
|
+
// ── Init & Wrap ────────────────────────────────────────────────────
|
|
1424
|
+
Sentry.init({ dsn: "...", release: "...", environment: "production" });
|
|
1425
|
+
export default Sentry.wrap(App); // required for touch breadcrumbs + feedback widget
|
|
1426
|
+
|
|
1427
|
+
// ── Capture ───────────────────────────────────────────────────────
|
|
1428
|
+
Sentry.captureException(new Error("oh no"));
|
|
1429
|
+
Sentry.captureMessage("Something happened", "warning");
|
|
1430
|
+
Sentry.captureEvent({ message: "raw event", level: "info" });
|
|
1431
|
+
|
|
1432
|
+
// ── Identity & Context ────────────────────────────────────────────
|
|
1433
|
+
Sentry.setUser({ id: "42", email: "user@example.com" });
|
|
1434
|
+
Sentry.setTag("version", "3.2.1");
|
|
1435
|
+
Sentry.setContext("order", { id: "ORD-99", total: 59.99 });
|
|
1436
|
+
|
|
1437
|
+
// ── Scopes ────────────────────────────────────────────────────────
|
|
1438
|
+
Sentry.withScope((scope) => {
|
|
1439
|
+
scope.setTag("temp", "value");
|
|
1440
|
+
Sentry.captureException(err);
|
|
1441
|
+
});
|
|
1442
|
+
Sentry.getGlobalScope().setTag("app", "mobile");
|
|
1443
|
+
Sentry.getCurrentScope().clear();
|
|
1444
|
+
|
|
1445
|
+
// ── Breadcrumbs ───────────────────────────────────────────────────
|
|
1446
|
+
Sentry.addBreadcrumb({ category: "auth", message: "Login", level: "info" });
|
|
1447
|
+
|
|
1448
|
+
// ── Error Boundaries ──────────────────────────────────────────────
|
|
1449
|
+
<Sentry.ErrorBoundary
|
|
1450
|
+
fallback={({ error, resetError }) => (
|
|
1451
|
+
<View><Text>{error.toString()}</Text><Button onPress={resetError} title="Retry" /></View>
|
|
1452
|
+
)}
|
|
1453
|
+
beforeCapture={(scope) => scope.setTag("section", "main")}
|
|
1454
|
+
>
|
|
1455
|
+
<App />
|
|
1456
|
+
</Sentry.ErrorBoundary>
|
|
1457
|
+
|
|
1458
|
+
// ── Event Processor ───────────────────────────────────────────────
|
|
1459
|
+
Sentry.addEventProcessor((event) => { event.extra = { foo: "bar" }; return event; });
|
|
1460
|
+
```
|
|
1461
|
+
|
|
1462
|
+
---
|
|
1463
|
+
|
|
1464
|
+
## 21. Troubleshooting
|
|
1465
|
+
|
|
1466
|
+
| Issue | Solution |
|
|
1467
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1468
|
+
| Events not appearing in Sentry | Check DSN is correct; set `debug: true` to see SDK logs; verify `enabled: true`; check for `beforeSend` returning `null` |
|
|
1469
|
+
| Native crashes not reported | Ensure `enableNative: true` and `enableNativeCrashHandling: true`; check that native SDKs initialized (look for `onReady` callback firing) |
|
|
1470
|
+
| ANR/hang events not appearing | Android ANR is always on; for iOS, verify `enableAppHangTracking: true` and try lowering `appHangTimeoutInterval` |
|
|
1471
|
+
| `Sentry.wrap` not working | Confirm it wraps the **root component** registered with `AppRegistry` (not an inner component) |
|
|
1472
|
+
| `showFeedbackWidget()` crashes | App must be wrapped with `Sentry.wrap(App)`; ensure Fabric (new arch) requires RN ≥ 0.71 |
|
|
1473
|
+
| Screenshots are blank | Screenshot capture may be blocked on certain Android versions; ensure `attachScreenshot: true` |
|
|
1474
|
+
| `beforeSend` not filtering native crashes | `beforeSend` only filters JS-layer events; native crashes bypass it — use `enableNativeCrashHandling: false` to disable native crash capture entirely |
|
|
1475
|
+
| Duplicate events appearing | Check for multiple `Sentry.init()` calls; `Dedupe` integration handles sequential duplicates but not concurrent ones |
|
|
1476
|
+
| Too many breadcrumbs / events | Reduce `maxBreadcrumbs`; use `beforeBreadcrumb` to filter; use `sampleRate` to reduce event volume |
|
|
1477
|
+
| HTTP errors not captured | Add `enableCaptureFailedRequests: true` (v5.3.0+) or configure `httpClientIntegration()` |
|
|
1478
|
+
| Missing stack frames (minified) | Upload source maps via Sentry CLI or the Metro plugin; check `dist` and `release` match the build |
|
|
1479
|
+
| `setContext` data not appearing | Verify key `"type"` is not used (reserved); check `normalizeDepth` isn’t truncating nested data |
|
|
1480
|
+
| Event payload rejected with 413 | Attachment or context too large; use `stateTransformer` in Redux enhancer; limit attachment sizes |
|
|
1481
|
+
| Offline events not sent | Events are sent on next app launch (Android) or next event fire (iOS); check `maxCacheItems` isn’t set too low |
|