Skip to content

Commit 2d9523e

Browse files
authored
Merge branch 'main' into markushi/feat/cursor-rules
2 parents a43110e + 514ac01 commit 2d9523e

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
### Fixes
66

77
- Allow multiple UncaughtExceptionHandlerIntegrations to be active at the same time ([#4462](https://github.com/getsentry/sentry-java/pull/4462))
8+
- Prevent repeated scroll target determination during a single scroll gesture ([#4557](https://github.com/getsentry/sentry-java/pull/4557))
9+
- This should reduce the number of ANRs seen in `SentryGestureListener`
810

911
## 8.17.0
1012

sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public boolean onScroll(
139139
options
140140
.getLogger()
141141
.log(SentryLevel.DEBUG, "Unable to find scroll target. No breadcrumb captured.");
142+
scrollState.type = GestureType.Scroll;
142143
return false;
143144
} else {
144145
options

sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import android.widget.AbsListView
1111
import android.widget.ListAdapter
1212
import androidx.core.view.ScrollingView
1313
import io.sentry.Breadcrumb
14+
import io.sentry.ILogger
1415
import io.sentry.IScope
1516
import io.sentry.IScopes
1617
import io.sentry.PropagationContext
1718
import io.sentry.Scope
1819
import io.sentry.ScopeCallback
20+
import io.sentry.SentryLevel
1921
import io.sentry.SentryLevel.INFO
2022
import io.sentry.android.core.SentryAndroidOptions
2123
import kotlin.test.Test
@@ -28,6 +30,7 @@ import org.mockito.kotlin.doAnswer
2830
import org.mockito.kotlin.inOrder
2931
import org.mockito.kotlin.mock
3032
import org.mockito.kotlin.never
33+
import org.mockito.kotlin.times
3134
import org.mockito.kotlin.verify
3235
import org.mockito.kotlin.verifyNoMoreInteractions
3336
import org.mockito.kotlin.whenever
@@ -56,7 +59,7 @@ class SentryGestureListenerScrollTest {
5659
val directions = setOf("up", "down", "left", "right")
5760

5861
internal inline fun <reified T : View> getSut(
59-
resourceName: String = "test_scroll_view",
62+
resourceName: String? = "test_scroll_view",
6063
touchWithinBounds: Boolean = true,
6164
direction: String = "",
6265
): SentryGestureListener {
@@ -229,6 +232,22 @@ class SentryGestureListenerScrollTest {
229232
verify(fixture.scope).propagationContext = any()
230233
}
231234

235+
@Test
236+
fun `logs error message only once per gesture when no scroll target is found`() {
237+
val logger = mock<ILogger>()
238+
fixture.options.setLogger(logger)
239+
fixture.options.isDebug = true
240+
val sut = fixture.getSut<ScrollableListView>(resourceName = null)
241+
242+
sut.onDown(fixture.firstEvent)
243+
fixture.eventsInBetween.forEach { sut.onScroll(fixture.firstEvent, it, 10.0f, 0f) }
244+
sut.onUp(fixture.endEvent)
245+
246+
// Verify that the error message is logged only once during the entire gesture
247+
verify(logger, times(1))
248+
.log(SentryLevel.DEBUG, "Unable to find scroll target. No breadcrumb captured.")
249+
}
250+
232251
internal class ScrollableView : View(mock()), ScrollingView {
233252
override fun computeVerticalScrollOffset(): Int = 0
234253

sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/ViewHelpers.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ internal inline fun <reified T : View> mockView(
6767
return mockView
6868
}
6969

70-
internal fun Resources.mockForTarget(target: View, expectedResourceName: String) {
71-
whenever(getResourceEntryName(target.id)).thenReturn(expectedResourceName)
70+
internal fun Resources.mockForTarget(target: View, expectedResourceName: String?) {
71+
if (expectedResourceName == null) {
72+
whenever(getResourceEntryName(target.id))
73+
.thenThrow(Resources.NotFoundException("res not found"))
74+
} else {
75+
whenever(getResourceEntryName(target.id)).thenReturn(expectedResourceName)
76+
}
7277
}

0 commit comments

Comments
 (0)