Skip to content

Commit cf230cd

Browse files
adinauerclaude
andcommitted
fix(spring): [Cache Tracing 24] Track invalidate cache.write accurately
Set cache.write based on delegate.invalidate() result instead of always true. This keeps span data aligned with Spring's invalidate semantics when no entries were present. Add tests in spring, spring-jakarta, and spring-7 wrappers to cover the false return path and assert cache.write is false. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 616aeab commit cf230cd

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

sentry-spring-7/src/main/java/io/sentry/spring7/cache/SentryCacheWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public boolean invalidate() {
287287
}
288288
try {
289289
final boolean result = delegate.invalidate();
290-
span.setData(SpanDataConvention.CACHE_WRITE, true);
290+
span.setData(SpanDataConvention.CACHE_WRITE, result);
291291
span.setStatus(SpanStatus.OK);
292292
return result;
293293
} catch (Throwable e) {

sentry-spring-7/src/test/kotlin/io/sentry/spring7/cache/SentryCacheWrapperTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import kotlin.test.BeforeTest
1313
import kotlin.test.Test
1414
import kotlin.test.assertEquals
1515
import kotlin.test.assertFailsWith
16+
import kotlin.test.assertFalse
1617
import kotlin.test.assertNull
1718
import kotlin.test.assertTrue
1819
import org.mockito.kotlin.any
@@ -450,6 +451,21 @@ class SentryCacheWrapperTest {
450451
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
451452
}
452453

454+
@Test
455+
fun `invalidate sets cache write false when cache had no mappings`() {
456+
val tx = createTransaction()
457+
val wrapper = SentryCacheWrapper(delegate, scopes)
458+
whenever(delegate.invalidate()).thenReturn(false)
459+
460+
val result = wrapper.invalidate()
461+
462+
assertFalse(result)
463+
assertEquals(1, tx.spans.size)
464+
assertEquals("cache.invalidate", tx.spans.first().operation)
465+
assertEquals(false, tx.spans.first().getData(SpanDataConvention.CACHE_WRITE))
466+
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
467+
}
468+
453469
// -- no span when no active transaction --
454470

455471
@Test

sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public boolean invalidate() {
287287
}
288288
try {
289289
final boolean result = delegate.invalidate();
290-
span.setData(SpanDataConvention.CACHE_WRITE, true);
290+
span.setData(SpanDataConvention.CACHE_WRITE, result);
291291
span.setStatus(SpanStatus.OK);
292292
return result;
293293
} catch (Throwable e) {

sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/cache/SentryCacheWrapperTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import kotlin.test.BeforeTest
1313
import kotlin.test.Test
1414
import kotlin.test.assertEquals
1515
import kotlin.test.assertFailsWith
16+
import kotlin.test.assertFalse
1617
import kotlin.test.assertNull
1718
import kotlin.test.assertTrue
1819
import org.mockito.kotlin.any
@@ -450,6 +451,21 @@ class SentryCacheWrapperTest {
450451
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
451452
}
452453

454+
@Test
455+
fun `invalidate sets cache write false when cache had no mappings`() {
456+
val tx = createTransaction()
457+
val wrapper = SentryCacheWrapper(delegate, scopes)
458+
whenever(delegate.invalidate()).thenReturn(false)
459+
460+
val result = wrapper.invalidate()
461+
462+
assertFalse(result)
463+
assertEquals(1, tx.spans.size)
464+
assertEquals("cache.invalidate", tx.spans.first().operation)
465+
assertEquals(false, tx.spans.first().getData(SpanDataConvention.CACHE_WRITE))
466+
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
467+
}
468+
453469
// -- no span when no active transaction --
454470

455471
@Test

sentry-spring/src/main/java/io/sentry/spring/cache/SentryCacheWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public boolean invalidate() {
214214
}
215215
try {
216216
final boolean result = delegate.invalidate();
217-
span.setData(SpanDataConvention.CACHE_WRITE, true);
217+
span.setData(SpanDataConvention.CACHE_WRITE, result);
218218
span.setStatus(SpanStatus.OK);
219219
return result;
220220
} catch (Throwable e) {

sentry-spring/src/test/kotlin/io/sentry/spring/cache/SentryCacheWrapperTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlin.test.BeforeTest
1111
import kotlin.test.Test
1212
import kotlin.test.assertEquals
1313
import kotlin.test.assertFailsWith
14+
import kotlin.test.assertFalse
1415
import kotlin.test.assertNull
1516
import kotlin.test.assertTrue
1617
import org.mockito.kotlin.any
@@ -274,6 +275,21 @@ class SentryCacheWrapperTest {
274275
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
275276
}
276277

278+
@Test
279+
fun `invalidate sets cache write false when cache had no mappings`() {
280+
val tx = createTransaction()
281+
val wrapper = SentryCacheWrapper(delegate, scopes)
282+
whenever(delegate.invalidate()).thenReturn(false)
283+
284+
val result = wrapper.invalidate()
285+
286+
assertFalse(result)
287+
assertEquals(1, tx.spans.size)
288+
assertEquals("cache.invalidate", tx.spans.first().operation)
289+
assertEquals(false, tx.spans.first().getData(SpanDataConvention.CACHE_WRITE))
290+
assertEquals("invalidate", tx.spans.first().getData(SpanDataConvention.CACHE_OPERATION))
291+
}
292+
277293
// -- no span when no active transaction --
278294

279295
@Test

0 commit comments

Comments
 (0)