Skip to content

fix(core): [Callback Errors 3] Drop failed processor data - #6142

Open
adinauer wants to merge 3 commits into
fix/callback-error-handling-processor-markerfrom
fix/callback-error-handling-event-processors
Open

adinauer wants to merge 3 commits into
fix/callback-error-handling-processor-markerfrom
fix/callback-error-handling-event-processors

Conversation

@adinauer

@adinauer adinauer commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

PR Stack (Callback Errors)


📜 Description

Drops the current telemetry item when a customer EventProcessor throws. Subsequent processors and beforeSend* callbacks do not run, and the item is not sent or added to a batch.

SDK-owned processors are identified by the internal SentryEventProcessor marker from #6162. Their exceptions are logged, but processing continues with the current item, including subsequent processors and beforeSend* callbacks. No callback_error client-report outcome or OnDiscardCallback notification is emitted for an SDK processor failure because the item is not dropped.

Customer processor exceptions record callback_error outcomes for errors, transactions and spans, replays, feedback, logs and log bytes, and metrics and metric bytes. Intentional processor null results continue to use event_processor, including for SDK-owned processors. Existing accounting for spans actually removed by a processor is preserved.

The distinction applies regardless of registration through options or scope. Replay processors only run from options. The marker identifies the implementation hierarchy; customer subclasses of SDK processors inherit the marker.

💡 Motivation and Context

Continuing after a customer processor failure can send partially processed data, including data that the processor intended to scrub. Fail closed for customer code while preserving the existing continue-on-error behavior for SDK-owned processors. Client reports represent discarded telemetry, not internal exceptions that do not cause a drop.

💚 How did you test it?

  • ./gradlew spotlessApply apiDump
  • ./gradlew :sentry:test --tests io.sentry.SentryClientTest --tests io.sentry.SentryClientInternalEventProcessorTest --tests io.sentry.ScopeTest --tests io.sentry.ScopesTest --tests io.sentry.clientreport.ClientReportTest --tests io.sentry.internal.eventprocessor.SentryEventProcessorTest :sentry:apiCheck :sentry:spotlessCheck — 588 tests passed
  • Added regression coverage for SDK failures across all six processing paths, scope/options registration, subsequent processors and callbacks, transport/batch delivery, error logging, and absence of discard accounting.
  • Verified customer failures still drop data, SDK processors returning null still drop intentionally, and actual span removals retain their accounting. Before the SDK-specific guards, 15 new regression cases failed; all pass with the change.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

The final stack PR changes beforeBreadcrumb exception handling. Profile/replay artifact cleanup and profile discard accounting remain separate follow-ups; this update only distinguishes SDK-owned and customer processors. Existing catch types are unchanged.

⚠️ Merge this PR using a merge commit (not squash). Only the collection branch is squash-merged into main.

Stop processing and drop telemetry when an event processor throws. Record callback_error outcomes for every supported category instead of sending potentially partially processed data.

Refs #6081
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor
Fails
🚫 Please consider adding a changelog entry for the next release.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

### Fixes

- [Callback Errors 3] Drop failed processor data ([#6142](https://github.com/getsentry/sentry-java/pull/6142))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description or adding a skip-changelog label.

Generated by 🚫 dangerJS against 6d07426

@sentry

sentry Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.57.0 (1) release

⚙️ sentry-android Build Distribution Settings

Comment thread sentry/src/main/java/io/sentry/SentryClient.java
@adinauer adinauer changed the title fix(core): [Callback Errors 2] Drop failed processor data fix(core): [Callback Errors 3] Drop failed processor data Sep 24, 2026
@adinauer
adinauer changed the base branch from fix/callback-error-handling-discard-reason to fix/callback-error-handling-processor-marker September 24, 2026 12:49
adinauer and others added 2 commits September 24, 2026 14:50
Make the preceding marker PR available to the processor failure policy.
Preserve the existing stack commits and leave failure behavior unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Use the internal processor marker to continue processing after SDK-owned
processor failures without recording callback_error losses. Keep customer
processor failures fail-closed across events, transactions, replays,
feedback, logs, and metrics.

Cover scope and options registration, continued callbacks and delivery,
logging without discard notifications, intentional drops, and span loss
accounting. Clarify the customer-only failure policy in the changelog.

Refs #6081
Co-Authored-By: Claude <noreply@anthropic.com>
Comment on lines 564 to 573
e,
"An exception occurred while processing log event by processor: %s",
processor.getClass().getName());
if (!(processor instanceof SentryEventProcessor)) {
recordLostLogEvent(DiscardReason.CALLBACK_ERROR, eventBeforeProcessor);
return null;
}
}

if (event == null) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: When a transaction is dropped by a processTransaction event processor, the subsequent debug log message incorrectly attributes the drop to applyScope.
Severity: LOW

Suggested Fix

Update the debug log message to accurately reflect the source of the transaction drop. This could involve adding a separate log message within the processTransaction method when an exception occurs, or adding a check to differentiate between a drop from applyScope and a drop from processTransaction before logging.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: sentry/src/main/java/io/sentry/SentryClient.java#L564-L573

Potential issue: When a transaction is captured, if a scope event processor throws an
exception, the `processTransaction` method correctly returns `null` to drop the
transaction. However, a subsequent debug log message at `SentryLevel.DEBUG` incorrectly
states "Transaction was dropped by applyScope". This is misleading because the drop was
caused by the event processor in `processTransaction`, not by the `applyScope` method
itself. While the functional behavior of dropping the transaction and recording a
`CALLBACK_ERROR` is correct, the log message is inaccurate and could cause confusion
during debugging.

adinauer added a commit that referenced this pull request Sep 24, 2026
Merge #6142 forward into #6143 so SDK-owned processor failures preserve\ntelemetry throughout the stack. Keep the breadcrumb-only diff unchanged\nand retain both changelog entries without rewriting existing history.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant