Skip to content

Commit 1411bb7

Browse files
committed
fix(spring-jakarta): Close leaked Kafka interceptor scope
Store the lifecycle token in the thread-local before trace continuation or transaction startup can throw. This keeps the cleanup path reachable and closes the forked scopes even when interceptor preparation fails. Also log the preparation failure instead of letting the interceptor break customer processing.
1 parent db18ff8 commit 1411bb7

1 file changed

Lines changed: 13 additions & 9 deletions

File tree

sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/kafka/SentryKafkaRecordInterceptor.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.sentry.IScopes;
66
import io.sentry.ISentryLifecycleToken;
77
import io.sentry.ITransaction;
8+
import io.sentry.SentryLevel;
89
import io.sentry.SentryTraceHeader;
910
import io.sentry.SpanDataConvention;
1011
import io.sentry.SpanStatus;
@@ -57,18 +58,21 @@ public SentryKafkaRecordInterceptor(
5758
return delegateIntercept(record, consumer);
5859
}
5960

60-
finishStaleContext();
61-
62-
final @NotNull IScopes forkedScopes = scopes.forkedRootScopes("SentryKafkaRecordInterceptor");
63-
final @NotNull ISentryLifecycleToken lifecycleToken = forkedScopes.makeCurrent();
64-
currentContext.set(new SentryRecordContext(lifecycleToken, null));
61+
try {
62+
finishStaleContext();
6563

66-
final @Nullable TransactionContext transactionContext = continueTrace(forkedScopes, record);
64+
final @NotNull IScopes forkedScopes = scopes.forkedRootScopes("SentryKafkaRecordInterceptor");
65+
final @NotNull ISentryLifecycleToken lifecycleToken = forkedScopes.makeCurrent();
66+
currentContext.set(new SentryRecordContext(lifecycleToken, null));
6767

68-
final @Nullable ITransaction transaction =
69-
startTransaction(forkedScopes, record, transactionContext);
70-
currentContext.set(new SentryRecordContext(lifecycleToken, transaction));
68+
final @Nullable TransactionContext transactionContext = continueTrace(forkedScopes, record);
7169

70+
final @Nullable ITransaction transaction =
71+
startTransaction(forkedScopes, record, transactionContext);
72+
currentContext.set(new SentryRecordContext(lifecycleToken, transaction));
73+
} catch (Throwable t) {
74+
scopes.getOptions().getLogger().log(SentryLevel.ERROR, "Unable to wrap Kafka consumer.", t);
75+
}
7276
return delegateIntercept(record, consumer);
7377
}
7478

0 commit comments

Comments
 (0)