@setoelkahfi / svara / commits / c9235dc

feat!: added timeout if directory loading takes too long

mellbacon committed Jul 15, 2023 at 18:13 UTC c9235dc7831bb07a070ec3a034d0ddb4292ac866
1 file changed +59 -9
src/lib/File.ts
+59 -9
@@ -12,37 +12,87 @@ export async function openFile() {
12 }
13
14 export const workspaceName = writable("Untitled Workspace");
15 +export const dirToLoad = writable("");
16 +export const dirLoadFail = writable(false);
17 export async function openFolder() {
18 + dirLoadFail.set(false);
19 let directory = await dialog.open({directory: true}) as string;
20 if (!directory) return;
18 -
21 + dirToLoad.set(directory.split(path.sep).pop());
22 // if file path is not in the configured scope already, add it
23 // TODO: should configure this so it doesnt access restricted paths based on user permissions
24 await invoke("attempt_file_access", {app_handle: window, p: directory});
25
26 const directoryName = await updateTree(directory);
24 - workspaceName.set(directoryName);
25 -
27 + if (!directoryName) {
28 + return;
29 + }
30 // load file watcher
31 await watch(
32 directory,
29 - async () => {
30 - await updateTree(directory);
33 + () => {
34 + updateTree(directory);
35 },
36 { recursive: true }
37 )
38 +
39 + workspaceName.set(directoryName);
40 }
41
42 +export const treeLoading = writable(false);
43 +let progressTimeout = null;
44 +let loadInterval = null;
45 async function updateTree(directory) {
37 - let tree: any = await fs.readDir(directory, {recursive: true});
38 - if (!tree) {
46 + let loadTime = 0;
47 +
48 + clearTimeout(progressTimeout);
49 + clearInterval(loadInterval);
50 + treeLoading.set(true);
51 + loadInterval = setInterval(() => {loadTime++}, 1000)
52 + let tree;
53 + try {
54 + tree = await fs.readDir(directory, {recursive: true});
55 + } catch (error) {
56 + console.error(error);
57 + }
58 + if (!tree || tree === undefined) {
59 console.error("Cannot load directory");
40 - return;
60 +
61 + clearInterval(loadInterval);
62 +
63 + dirLoadFail.set(true);
64 + dirToLoad.set("Cannot load directory");
65 +
66 + progressTimeout = setTimeout(() => {
67 + treeLoading.set(false);
68 + }, 5000)
69 + return null;
70 + }
71 + if (loadTime > 100) {
72 + console.error(`Directory load time was too long. Aborting...`);
73 + console.warn(`Cancelled load after ${loadTime} seconds`);
74 + clearInterval(loadInterval);
75 +
76 + dirLoadFail.set(true);
77 + dirToLoad.set("Error: Directory load timeout.");
78 +
79 + progressTimeout = setTimeout(() => {
80 + treeLoading.set(false);
81 + }, 5000)
82 + return null;
83 }
42 - let directoryName = directory.split(path.sep).pop();
84 + let directoryName = get(dirToLoad);
85 tree = [{id: -1, name: directoryName, path: directory, children: buildTree(sortTree(tree))}];
86 filetree.set(tree);
87 + clearInterval(loadInterval);
88 + if (loadTime < 45) {
89 + console.log(`Directory load time: ${loadTime < 1 ? "less than 1" : loadTime}s`);
90 + }
91 + else {
92 + console.warn(`Directory load time: ${loadTime < 1 ? "less than 1" : loadTime}s`);
93 + }
94 id = 0;
95 + treeLoading.set(false);
96 return directoryName;
97 }
98