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

Aperta Adatta ai principianti
#17,533 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
84/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
kotlin
Ambito
mobile

Direzione di ricerca

Inizia in FileHelper.kt, in listDirectoryEntries, e verifica come Files.list() segnala gli errori durante l’iterazione terminale; poi controlla in LocalFileListAdapter.kt, in loadRemainingEntries(), il confine dell’attività in background. Conferma che gli errori nella lettura di una directory non terminino più l’app, che il picker mantenga le voci leggibili o mostri un elenco vuoto, e se il fix debba essere sottoposto a backport sulla linea 34.1.1.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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
Lingua principale
Kotlin
Stelle
5.6k
Fork
2k
Merge medio
1g 21h
PR unite (30g)
101

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nextcloud/android

Tutte le issue di nextcloud/android

Issue simili

Altre issue su Kotlin

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.