Skip to content

Commit d858534

Browse files
committed
fix: prevent NotFoundError when drag-dropping large folders
Browsers discard stale FileSystemEntry references during long sequential uploads. For folders with 500+ files, later entries become unreachable by the time processNextFile gets to them. Read all directory entries upfront and resolve File handles immediately before starting any uploads.
1 parent 843bd70 commit d858534

1 file changed

Lines changed: 27 additions & 10 deletions

File tree

src/modules/upload/index.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,21 @@ const getFileFromEntry = entry =>
323323
const readNextBatch = dirReader =>
324324
new Promise((resolve, reject) => dirReader.readEntries(resolve, reject))
325325

326+
/**
327+
* Read all entries from a directory upfront so file entries can be
328+
* converted to File objects before uploads start. This prevents
329+
* NotFoundError when the browser discards stale FileSystemEntry
330+
* references during long sequential uploads of large directories.
331+
*/
332+
const readAllEntries = async dirReader => {
333+
const entries = []
334+
let batch
335+
while ((batch = await readNextBatch(dirReader)).length > 0) {
336+
entries.push(...batch)
337+
}
338+
return entries
339+
}
340+
326341
const uploadDirectory = async (
327342
client,
328343
directory,
@@ -334,16 +349,18 @@ const uploadDirectory = async (
334349
const dirReader = directory.createReader()
335350
const options = { vaultClient, encryptionKey }
336351

337-
// readEntries returns batches (typically ≤100 entries); loop until empty
338-
let batch
339-
while ((batch = await readNextBatch(dirReader)).length > 0) {
340-
for (const entry of batch) {
341-
if (entry.isFile) {
342-
const file = await getFileFromEntry(entry)
343-
await uploadFile(client, file, newDir.id, options, driveId)
344-
} else if (entry.isDirectory) {
345-
await uploadDirectory(client, entry, newDir.id, options, driveId)
346-
}
352+
const entries = await readAllEntries(dirReader)
353+
354+
const files = await Promise.all(
355+
entries.filter(e => e.isFile).map(e => getFileFromEntry(e))
356+
)
357+
358+
let fileIndex = 0
359+
for (const entry of entries) {
360+
if (entry.isFile) {
361+
await uploadFile(client, files[fileIndex++], newDir.id, options, driveId)
362+
} else if (entry.isDirectory) {
363+
await uploadDirectory(client, entry, newDir.id, options, driveId)
347364
}
348365
}
349366

0 commit comments

Comments
 (0)