Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Android Replay: BufferCaptureStrategy.stop() can persist replay state after deleting replay cache dir

Đang mở
#6,094 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
70/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
android, kotlin
Lĩnh vực
mobile-dev

Hướng nghiên cứu

Bắt đầu với BufferCaptureStrategy.kt và ReplayCache.kt, theo dõi BufferCaptureStrategy.stop() qua setter của currentSegment và persistSegmentValues(). Tái hiện đường dẫn teardown của replay có buffering, đặc biệt sau khi xóa thư mục replay cache, và xác minh rằng việc dừng replay không còn ghi log lỗi No such file or directory.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Android Bug Platform: Java Replays
Problem Statement

Android Session Replay can throw an internal error during replay teardown:

Failed to execute task CaptureStrategy.runInBackground
java.io.IOException: No such file or directory
...
at io.sentry.android.replay.ReplayCache.persistSegmentValues
...
at io.sentry.android.replay.capture.BufferCaptureStrategy.stop

This appears to happen when stopping a buffering replay.

Likely root cause

BufferCaptureStrategy.stop() currently deletes the replay cache directory and then updates replay state in the same task:

  • delete replay cache dir
  • set currentSegment = -1

The currentSegment setter persists state through ReplayCache.persistSegmentValues(...).

On the replay worker thread, that persistence runs inline, so it can try to recreate/write .ongoing_segment after the replay directory has already been deleted.

That leads to:

java.io.IOException: No such file or directory
at java.io.File.createNewFile
at io.sentry.android.replay.ReplayCache.persistSegmentValues
Why this matters

This is at least noisy internal error logging, but it may also contribute to brittle replay lifecycle behavior in manual/custom flows that use combinations of:

  • flush()
  • pause()
  • stop()
  • startBuffering()

In our investigation, this showed up while testing a custom User Feedback + Replay workaround, where replay behavior was already timing-sensitive.

Relevant code path

Conceptually, the flow is:

  • BufferCaptureStrategy.stop()
  • FileUtils.deleteRecursively(replayCacheDir)
  • currentSegment = -1
  • persistSegmentValues(...)
  • ongoingSegmentFile?.createNewFile()
  • parent folder no longer exists
Expected behavior

Stopping replay should not try to persist replay state into a directory that has already been deleted.

Actual behavior

Replay teardown logs No such file or directory from ReplayCache.persistSegmentValues.

Suggested fix direction

Any of these would likely resolve it:

  • clear/persist mutable state before deleting the replay directory
  • mark the cache closed before state mutation can persist
  • guard persistSegmentValues against a missing/deleted parent directory during teardown
  • avoid persisting teardown sentinel values like currentSegment = -1 once shutdown has begun
Customer-visible context

This was observed during a real customer reproduction involving Android Session Replay plus custom in-app User Feedback, where the workaround flow exercised replay stop/restart behavior repeatedly.

Logs
Failed to execute task CaptureStrategy.runInBackground
java.io.IOException: No such file or directory
    at java.io.UnixFileSystem.createFileExclusively0(Native Method)
    at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:373)
    at java.io.File.createNewFile(File.java:1022)
    at io.sentry.android.replay.ReplayCache.persistSegmentValues$sentry_android_replay_release(ReplayCache.kt:290)
    at io.sentry.android.replay.capture.BaseCaptureStrategy$special$$inlined$persistableAtomic$default$2$2.invoke(BaseCaptureStrategy.kt:240)
    at io.sentry.android.replay.capture.BaseCaptureStrategy$special$$inlined$persistableAtomic$default$2.runInBackground(BaseCaptureStrategy.kt:227)
    at io.sentry.android.replay.capture.BaseCaptureStrategy$special$$inlined$persistableAtomic$default$2.setValue(BaseCaptureStrategy.kt:239)
    at io.sentry.android.replay.capture.BaseCaptureStrategy.setCurrentSegment(BaseCaptureStrategy.kt:88)
    at io.sentry.android.replay.capture.BufferCaptureStrategy.stop$lambda$0(BufferCaptureStrategy.kt:84)
Ngôn ngữ chính
Kotlin
Star
1.4k
Fork
478
Merge trung bình
2 ngày 20 giờ
Pull request đã merge (30 ngày)
71

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của getsentry/sentry-java

Tất cả issue của getsentry/sentry-java

Issue tương tự

Thêm issue về Kotlin

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.