Skip to content

Commit

Permalink
Do not crash if navigation breadcrumb has not destination
Browse files Browse the repository at this point in the history
  • Loading branch information
romtsn committed Feb 19, 2025
1 parent 1e5daad commit 0b2888a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ internal interface CaptureStrategy {
companion object {
private const val BREADCRUMB_START_OFFSET = 100L

// 5 minutes, otherwise relay will just drop it. Can prevent the case where the device
// time is wrong and the segment is too long.
private const val MAX_SEGMENT_DURATION = 1000L * 60 * 5

fun createSegment(
scopes: IScopes?,
options: SentryOptions,
Expand All @@ -76,7 +80,7 @@ internal interface CaptureStrategy {
events: Deque<RRWebEvent>
): ReplaySegment {
val generatedVideo = cache?.createVideoOf(
duration,
minOf(duration, MAX_SEGMENT_DURATION),
currentSegmentTimestamp.time,
segmentId,
height,
Expand Down Expand Up @@ -179,7 +183,9 @@ internal interface CaptureStrategy {
recordingPayload += rrwebEvent

// fill in the urls array from navigation breadcrumbs
if ((rrwebEvent as? RRWebBreadcrumbEvent)?.category == "navigation") {
if ((rrwebEvent as? RRWebBreadcrumbEvent)?.category == "navigation" &&
rrwebEvent.data?.getOrElse("to", { null }) is String
) {
urls.add(rrwebEvent.data!!["to"] as String)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,30 @@ class SessionCaptureStrategyTest {
)
}

@Test
fun `does not throw when navigation destination is not a String`() {
val now =
System.currentTimeMillis() + (fixture.options.sessionReplay.sessionSegmentDuration * 5)
val strategy = fixture.getSut(dateProvider = { now })
strategy.start(fixture.recorderConfig)

fixture.scope.addBreadcrumb(Breadcrumb().apply { category = "navigation" })

strategy.onScreenshotRecorded(mock<Bitmap>()) {}

verify(fixture.scopes).captureReplay(
check {
assertNull(it.urls?.firstOrNull())
},
check {
val breadcrumbEvents =
it.replayRecording?.payload?.filterIsInstance<RRWebBreadcrumbEvent>()
assertEquals("navigation", breadcrumbEvents?.first()?.category)
assertNull(breadcrumbEvents?.first()?.data?.get("to"))
}
)
}

@Test
fun `sets screen from scope as replay url`() {
fixture.scope.screen = "MainActivity"
Expand Down

0 comments on commit 0b2888a

Please sign in to comment.