Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Do not crash if navigation breadcrumb has not destination
  • Loading branch information
romtsn committed Feb 19, 2025
commit 0b2888a0d754fe51a0e00125952d7d2236c7b0bf
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
Loading