Local folder picker crashes the app: UncheckedIOException from Files.list() escapes the IOException catch in FileHelper.listDirectoryEntries

Đang mở Phù hợp với người mới
#17,533 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ó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
84/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
kotlin
Lĩnh vực
mobile

Hướng nghiên cứu

Bắt đầu trong FileHelper.kt tại listDirectoryEntries và kiểm tra cách Files.list() báo cáo lỗi trong quá trình lặp đầu cuối; sau đó kiểm tra ranh giới của tác vụ nền trong LocalFileListAdapter.kt tại loadRemainingEntries(). Xác nhận rằng các lỗi đọc thư mục không còn làm ứng dụng kết thúc, rằng picker giữ lại các mục có thể đọc hoặc hiển thị danh sách trống, và liệu bản sửa lỗi có cần được backport vào dòng 34.1.1 hay không.

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

Mô tả

0. Needs triage
⚠️ Before posting ⚠️
  • This is a bug, not a question or an enhancement.
  • I've searched for similar issues and didn't find a duplicate.
  • I've written a clear and descriptive title for this issue, not just "Bug" or "Crash".
  • I agree to follow Nextcloud's Code of Conduct.
Steps to reproduce
  1. Settings → Auto upload → ⋮ → "Set custom folder".
  2. In the local folder picker, browse into a large directory under /storage/emulated/0/Android/media/… (in my case com.whatsapp/WhatsApp/Media/WhatsApp Images, ~11 600 files, and its Sent subdirectory).
  3. Keep the device busy at the same time (several auto-upload rules were uploading in the background here).

The directory read fails part-way through iteration with Software caused connection abort from the emulated-storage layer. That failure is intermittent and I cannot trigger it on demand — but when it happens, the app dies instead of showing an empty/partial list.

Expected behaviour

A failed directory read is logged and the picker shows what it could read (the catch in FileHelper.listDirectoryEntries is clearly written with exactly that intent).

Actual behaviour

The whole app is killed. The exception escapes the background executor task, so there is no chance to recover.

The catch cannot fire, and this is visible in the source rather than inferred:

FileHelper.listDirectoryEntries (34.1.1) uses Files.list(...), whose lazy stream reports directory-read failures from the terminal operation as java.io.UncheckedIOException — a RuntimeException, not an IOException:

return try {
    Files.list(directory.toPath())
        .map { it.toFile() }
        …
        .collect(Collectors.toList())
} catch (e: IOException) {          // never reached for UncheckedIOException
    Log_OC.d(TAG, "listDirectoryEntries: $e")
    emptyList()
}

LocalFileListAdapter.loadRemainingEntries() calls it on a pool thread with no guard, so the UncheckedIOException terminates the thread and takes the process with it.

Two small notes that may save reviewer time:

  • Adding catch (e: UncheckedIOException) (or catching its cause) next to the existing IOException branch restores the intended behaviour.
  • FileHelper on master has since been rewritten to forEachDirectoryPage using Files.newDirectoryStream with catch (IOException) + catch (DirectoryIteratorException), which does cover the iteration failure. So master may already be fine and this report is mainly about the released 34.1.1 line — worth confirming whether a backport is wanted.
Android version

17

Device brand and model

Samsung SM-F976B (Galaxy Z Fold8), stock

Stock or custom OS?

Stock

Nextcloud android app version

34.1.1 (340010190, gplay)

Nextcloud server version

31.0.14

Using a reverse proxy?

Yes

Android logs
Cause of error
Exception in thread "pool-27-thread-1" java.io.UncheckedIOException: java.nio.file.FileSystemException: /storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Images/Sent: Software caused connection abort
    at java.nio.file.Files$2.hasNext(Files.java:3729)
    at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1949)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:156)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:592)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:578)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:564)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:267)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:748)
    at com.nextcloud.utils.FileHelper.listDirectoryEntries(FileHelper.kt:31)
    at com.owncloud.android.ui.adapter.LocalFileListAdapter.loadRemainingEntries(LocalFileListAdapter.java:434)
    at com.owncloud.android.ui.adapter.LocalFileListAdapter.lambda$swapDirectory$2(LocalFileListAdapter.java:405)
    at com.owncloud.android.ui.adapter.LocalFileListAdapter.$r8$lambda$EFQ1jO9hT3yhM5CFqUk4qO5Vyvg(LocalFileListAdapter.java:0)
    at com.owncloud.android.ui.adapter.LocalFileListAdapter$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1100)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:1572)
Caused by: java.nio.file.FileSystemException: /storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Images/Sent: Software caused connection abort
    at sun.nio.fs.UnixDirectoryStream$UnixDirectoryIterator.readNextEntry(UnixDirectoryStream.java:180)
    at sun.nio.fs.UnixDirectoryStream$UnixDirectoryIterator.hasNext(UnixDirectoryStream.java:210)
    at java.nio.file.Files$2.hasNext(Files.java:3727)
    …
App information
  • ID: com.nextcloud.client
  • Version: 340010190
  • Build flavor: gplay
Device information
  • Brand: samsung
  • Device: q8q
  • Model: SM-F976B
  • Id: CP2A.260605.016
  • Product: q8qxeea
Firmware
  • SDK: 37
  • Release: 17
  • Incremental: F976BXXS2AZH7
Ngôn ngữ chính
Kotlin
Star
5.6k
Fork
2k
Merge trung bình
1 ngày 21 giờ
Pull request đã merge (30 ngày)
101

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 nextcloud/android

Tất cả issue của nextcloud/android

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.