This file provides guidance to AI coding agents when working with code in this repository.
This file covers the whole repository. Before working on a specific area, read the matching
rule file in .cursor/rules/:
| Rule | Read it when working on |
|---|---|
api |
Public API surface, binary compatibility, .api files, apiDump, IScope/IScopes/Sentry static API, protocol classes |
options |
SentryOptions, namespaced options, ExternalOptions, sentry.properties, ManifestMetadataReader, Spring Boot properties |
scopes |
Scope management, forking, lifecycle, ScopeType, thread-local storage, scope bleeding, Hub → Scopes migration |
deduplication |
Duplicate event detection, DuplicateEventDetectionEventProcessor, enableDeduplication |
offline |
Caching, envelope storage, network failure handling, retries, AsyncHttpTransport, EnvelopeCache, rate limiting |
feature_flags |
addFeatureFlag, FeatureFlagBuffer, maxFeatureFlags, LaunchDarkly and OpenFeature integrations |
metrics |
Sentry.metrics(), IMetricsApi, count/distribution/gauge, MetricsBatchProcessor |
queues |
Queue tracing, queue.publish/queue.process, enableQueueTracing, Kafka instrumentation, messaging span data |
continuous_profiling_jvm |
sentry-async-profiler, IContinuousProfiler, ProfileChunk, JFR files, ProfileLifecycle |
opentelemetry |
sentry-opentelemetry-*, agent vs agentless, span processing, sampling, context propagation |
new_module |
Adding a new integration or sample module |
e2e_tests |
System tests, sample applications, system-test-runner.py, mock Sentry server |
Rules can be combined — a tracing scope issue may need both scopes and opentelemetry.
There is no rule for Android profiling yet; read the sentry-android-core profiling code
directly and fetch related rules such as options, offline, or api as needed.
This is the Sentry Java/Android SDK - a comprehensive error monitoring and performance tracking SDK for Java and Android applications. The repository contains multiple modules for different integrations and platforms.
The project uses Gradle with Kotlin DSL. Key build files:
build.gradle.kts- Root build configurationsettings.gradle.kts- Multi-module project structurebuildSrc/andbuild-logic/- Custom build logic and pluginsMakefile- High-level build commands
# Format code and regenerate .api files (REQUIRED before committing)
./gradlew spotlessApply apiDump
# Run all tests and linter
./gradlew check
# Generate documentation
./gradlew aggregateJavadocs# Run unit tests for a specific file
./gradlew ':<module>:testReleaseUnitTest' --tests="*<file name>*" --info
# Run system tests (requires Python virtual env)
make systemTest
# Run specific test suites
./gradlew :sentry-android-core:testReleaseUnitTest
./gradlew :sentry:test# Check code formatting
./gradlew spotlessJavaCheck spotlessKotlinCheck
# Apply code formatting
./gradlew spotlessApply
# Update API dump files (after API changes)
./gradlew apiDump
# Dependency updates check
./gradlew dependencyUpdates -Drevision=release# Assemble Android test APKs
./gradlew :sentry-android-integration-tests:sentry-uitest-android:assembleRelease :sentry-android-integration-tests:sentry-uitest-android:assembleAndroidTest
# Run critical UI tests
./scripts/test-ui-critical.sh- First think through the problem: Read the codebase for relevant files and propose a plan
- Check in before beginning: Verify the plan before starting implementation
- Use todo tracking: Work through todo items, marking them as complete as you go
- High-level communication: Give high-level explanations of changes made, not step-by-step descriptions
- Simplicity first: Make every task and code change as simple as possible. Avoid massive or complex changes. Impact as little code as possible.
- Format and regenerate: Once done, format code and regenerate .api files:
./gradlew spotlessApply apiDump - Propose commit: As final step, git stage relevant files and propose (but not execute) a single git commit command. This applies to implementation work; when the task is to open a PR, the
create-java-prskill takes over from here and does commit, push, and open it.
This repo ships task-specific skills (declared in agents.toml, sources under .agents/skills). Prefer them over performing the steps manually:
create-java-pr: Branch, format,apiDump, commit, push, open PR, and add the changelog entry (automates the PR workflow above)test: Run unit or system tests for a module or a specific classcheck-code-attribution: Verify third-party code attribution on the current branch (see Third-Party Code Attribution below)btrace-perfetto: Capture and compare Perfetto traces for Android performance work
The repository is organized into multiple modules:
sentry- Core Java SDK implementationsentry-android-core- Core Android SDK implementationsentry-android- High-level Android SDKsentry-android-ndk- Native (NDK) crash handling
- Spring Framework:
sentry-spring*,sentry-spring-boot* - Logging:
sentry-logback,sentry-log4j2,sentry-jul,sentry-android-timber - Web:
sentry-servlet*,sentry-okhttp,sentry-openfeign,sentry-apache-http-client-5 - GraphQL:
sentry-graphql*,sentry-apollo* - Android UI:
sentry-android-fragment,sentry-android-navigation,sentry-compose - Session Replay:
sentry-android-replay - Database:
sentry-jdbc,sentry-android-sqlite,sentry-jcache - Reactive:
sentry-reactor,sentry-ktor-client - Feature Flags:
sentry-launchdarkly-android,sentry-launchdarkly-server,sentry-openfeature - Queues:
sentry-kafka - Profiling:
sentry-async-profiler(JVM continuous profiling) - Monitoring:
sentry-opentelemetry*,sentry-quartz - Other:
sentry-spotlight,sentry-kotlin-extensions,sentry-android-distribution
sentry-test-support- Shared test utilitiessentry-system-test-support- System testing infrastructuresentry-samples- Example applicationssentry-bom- Bill of Materials for dependency management
- Multi-platform: Supports JVM, Android, and Kotlin Multiplatform (Compose modules)
- Modular Design: Each integration is a separate module with minimal dependencies
- Options Pattern: Features are opt-in via
SentryOptionsand similar configuration classes - Transport Layer: Pluggable transport implementations for different environments
- Scope Management: Thread-safe scope/context management for error tracking
- Languages: Java 8+ and Kotlin
- Formatting: Enforced via Spotless - always run
./gradlew spotlessApplybefore committing - API Compatibility: Binary compatibility is enforced - run
./gradlew apiDumpafter API changes
Never introduce a new catch (Throwable). Catch the narrowest type the guarded code can
actually throw. The repository still contains many pre-existing broad catches; they are legacy,
not a precedent to follow.
A broad catch swallows OutOfMemoryError, StackOverflowError, ThreadDeath and LinkageError —
conditions the JVM/ART cannot recover from and that leave the process in an undefined state — and
it hides real bugs in our own code behind a log line.
"The SDK must never crash the host application" is not a reason to catch Throwable. That goal is
served by io.sentry.util.ExceptionUtils.rethrowIfFatal, which lets the non-recoverable throwables
through while leaving everything else for the caller to log or ignore:
try {
doSomethingRisky();
} catch (Throwable t) {
ExceptionUtils.rethrowIfFatal(t);
options.getLogger().log(SentryLevel.ERROR, "Failed to do something risky", t);
}Apply that pattern only where a broad catch is genuinely unavoidable — an entry point that runs arbitrary user code or third-party callbacks. Everywhere else, name the exception types. Say in the PR description why the broad catch is necessary.
- Write comprehensive unit tests for new features
- Android modules require both unit tests and instrumented tests where applicable
- System tests validate end-to-end functionality with sample applications
- Assertions: For new unit tests, prefer Google Truth (
com.google.common.truth.Truth.assertThat) overkotlin.test/JUnit assertions for its readable, fluent API. Keep usingkotlin.testfor test structure (@Test,assertFailsWith). Seesentry/src/test/java/io/sentry/DsnTest.ktfor the style. Don't rewrite existingkotlin.testassertions solely to switch libraries. - Truth is wired into the
sentrymodule. When adding Truth-based tests to another module, addtestImplementation(libs.google.truth)to that module'sbuild.gradle.kts.
- Follow existing code style and language
- Do not modify API files (e.g. sentry.api) manually - run
./gradlew apiDumpto regenerate them - Write comprehensive tests
- New features must be opt-in by default - extend
SentryOptionsor similar Option classes with getters/setters - Consider backwards compatibility
When adapting code from third-party libraries:
-
Add a license header at the top of the adapted file (before the
packagestatement):// Adapted from <Library Name>. // Copyright <year> <copyright holder>. // Licensed under the <License Name>. // <source URL>
-
Add a full attribution entry to
THIRD_PARTY_NOTICES.mdfollowing the existing format (Source, License, Copyright, Scope, full license text) -
Run the
check-code-attributionskill locally or wait for it to be auto-run against your PR to check for required fields and verify new licenses against Sentry's Open Source Legal Policy.
Use gh pr view to get PR details from the current branch. This is needed when adding changelog entries, which require the PR number.
# Get PR number for current branch
gh pr view --json number -q '.number'
# Get PR number for a specific branch
gh pr view <branch-name> --json number -q '.number'
# Get PR URL
gh pr view --json url -q '.url'User-facing changes get an entry under the ## Unreleased section of CHANGELOG.md. The
create-java-pr skill is the source of truth for the full changelog and PR workflow, including
subsection selection and the rebase caveat when a release renames ## Unreleased.
- Main SDK documentation: https://develop.sentry.dev/sdk/overview/
- Internal contributing guide: https://docs.sentry.io/internal/contributing/
- Git commit message conventions: https://develop.sentry.dev/engineering-practices/commit-messages/
This SDK is production-ready and used by thousands of applications. Changes should be thoroughly tested and maintain backwards compatibility.