fix: show which file and why knowledge directory sync failed (#29507)

Syncing a knowledge base from a local directory only ever showed a
generic "Error accessing directory" toast when a per-file read
failed, and production builds strip console.error, so nothing else
recorded the cause either. On Windows this hides a real Chromium bug
where files with very long absolute paths throw a NotFoundError from
the File System Access API, leaving no way to tell which file failed
or why.

Both per-file read paths (the directory picker and drag-and-drop) now
wrap read failures with the file's relative path and the underlying
browser error before they reach the toast, so the message actually
names the file and the reason. Reuses the existing translated toast
text instead of adding a new i18n key, so the fix doesn't orphan
existing translations of that string.
This commit is contained in:
Classic298 2026-09-13 00:55:31 +02:00 committed by GitHub
parent 51bb8cb142
commit ca8f151a12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -500,7 +500,7 @@
if (error.name === 'AbortError') {
toast.info($i18n.t('Directory selection was cancelled'));
} else {
toast.error($i18n.t('Error accessing directory'));
toast.error(`${$i18n.t('Error accessing directory')}: ${error.message}`);
console.error('Directory access error:', error);
}
};
@ -521,7 +521,12 @@
if (hasHiddenFolder(entryPath)) continue;
if (entry.kind === 'file') {
const file = await entry.getFile();
let file: File;
try {
file = await entry.getFile();
} catch (error) {
throw new Error(`"${entryPath}": ${error}`);
}
collected.push({ path: dirPath, filename: entry.name, file });
} else if (entry.kind === 'directory') {
await traverse(entry, entryPath);
@ -1021,9 +1026,14 @@
}
if (entry.isFile) {
const file = await new Promise<File>((resolve, reject) => {
entry.file(resolve, reject);
});
let file: File;
try {
file = await new Promise<File>((resolve, reject) => {
entry.file(resolve, reject);
});
} catch (error) {
throw new Error(`"${entryPath}": ${error}`);
}
const parts = entryPath.split('/');
const filename = parts.pop() || file.name;
return [{ path: parts.join('/'), filename, file }];