Add error resiliency to waitForPath

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton committed 2022-01-31 09:10:23 -05:00
1 parent 45907e8a2c
commit bc24aaa5ac
2 files changed
+67 -30

No files matched your search

+34 -11
View File
@@ -3,30 +3,53 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { watch } from "chokidar";
import { FSWatcher } from "chokidar";
import path from "path";
/**
* Wait for `filePath` and all parent directories to exist.
* @param filePath The file path to wait until it exists
* @param pathname The file path to wait until it exists
*
* NOTE: There is technically a race condition in this function of the form
* "time-of-check to time-of-use" because we have to wait for each parent
* directory to exist first.
*/
export async function waitForPath(filePath: string): Promise<void> {
const dirOfPath = path.dirname(filePath);
export async function waitForPath(pathname: string): Promise<void> {
const dirOfPath = path.dirname(pathname);
if (dirOfPath === filePath) {
if (dirOfPath === pathname) {
// The root of this filesystem, assume it exists
return;
} else {
await waitForPath(dirOfPath);
}
return new Promise(resolve => {
watch(dirOfPath, {
return new Promise((resolve, reject) => {
const watcher = new FSWatcher({
depth: 0,
}).on("all", (event, path) => {
if ((event === "add" || event === "addDir") && path === filePath) {
resolve();
}
disableGlobbing: true,
});
const onAddOrAddDir = (filePath: string) => {
if (filePath === pathname) {
watcher.unwatch(dirOfPath);
watcher
.close()
.then(() => resolve())
.catch(reject);
}
};
const onError = (error: any) => {
watcher.unwatch(dirOfPath);
watcher
.close()
.then(() => reject(error))
.catch(() => reject(error));
};
watcher
.on("add", onAddOrAddDir)
.on("addDir", onAddOrAddDir)
.on("error", onError)
.add(dirOfPath);
});
}