Skip to content

Commit c0d5c29

Browse files
authored
Reduce exceptions (microsoft#44710)
* Don't visit non-existent basePaths * Stop trying to add file watchers after hitting the system limit * Update tests
1 parent 066796b commit c0d5c29

File tree

5 files changed

+17
-7
lines changed

5 files changed

+17
-7
lines changed

src/compiler/sys.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@ namespace ts {
12661266
let activeSession: import("inspector").Session | "stopping" | undefined;
12671267
let profilePath = "./profile.cpuprofile";
12681268

1269+
let hitSystemWatcherLimit = false;
12691270

12701271
const Buffer: {
12711272
new (input: string, encoding?: string): any;
@@ -1619,6 +1620,12 @@ namespace ts {
16191620
options = { persistent: true };
16201621
}
16211622
}
1623+
1624+
if (hitSystemWatcherLimit) {
1625+
sysLog(`sysLog:: ${fileOrDirectory}:: Defaulting to fsWatchFile`);
1626+
return watchPresentFileSystemEntryWithFsWatchFile();
1627+
}
1628+
16221629
try {
16231630
const presentWatcher = _fs.watch(
16241631
fileOrDirectory,
@@ -1635,6 +1642,8 @@ namespace ts {
16351642
// Catch the exception and use polling instead
16361643
// Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
16371644
// so instead of throwing error, use fs.watchFile
1645+
hitSystemWatcherLimit ||= e.code === "ENOSPC";
1646+
sysLog(`sysLog:: ${fileOrDirectory}:: Changing to fsWatchFile`);
16381647
return watchPresentFileSystemEntryWithFsWatchFile();
16391648
}
16401649
}
@@ -1656,7 +1665,6 @@ namespace ts {
16561665
* Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
16571666
*/
16581667
function watchPresentFileSystemEntryWithFsWatchFile(): FileWatcher {
1659-
sysLog(`sysLog:: ${fileOrDirectory}:: Changing to fsWatchFile`);
16601668
return watchFile(
16611669
fileOrDirectory,
16621670
createFileWatcherCallback(callback),
@@ -1796,7 +1804,7 @@ namespace ts {
17961804
}
17971805

17981806
function readDirectory(path: string, extensions?: readonly string[], excludes?: readonly string[], includes?: readonly string[], depth?: number): string[] {
1799-
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
1807+
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath, directoryExists);
18001808
}
18011809

18021810
function fileSystemEntryExists(path: string, entryKind: FileSystemEntryKind): boolean {

src/compiler/utilities.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -6515,7 +6515,7 @@ namespace ts {
65156515
}
65166516

65176517
/** @param path directory of the tsconfig.json */
6518-
export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string): string[] {
6518+
export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string, directoryExists: (path: string) => boolean): string[] {
65196519
path = normalizePath(path);
65206520
currentDirectory = normalizePath(currentDirectory);
65216521

@@ -6531,7 +6531,9 @@ namespace ts {
65316531
const visited = new Map<string, true>();
65326532
const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames);
65336533
for (const basePath of patterns.basePaths) {
6534-
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
6534+
if (directoryExists(basePath)) {
6535+
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
6536+
}
65356537
}
65366538

65376539
return flatten(results);

src/compiler/watchUtilities.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ namespace ts {
184184
const rootResult = tryReadDirectory(rootDir, rootDirPath);
185185
let rootSymLinkResult: FileSystemEntries | undefined;
186186
if (rootResult !== undefined) {
187-
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath);
187+
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath, directoryExists);
188188
}
189189
return host.readDirectory!(rootDir, extensions, excludes, includes, depth);
190190

src/harness/fakesHosts.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ namespace fakes {
9595
}
9696

9797
public readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] {
98-
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path));
98+
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path), path => this.directoryExists(path));
9999
}
100100

101101
public getAccessibleFileSystemEntries(path: string): ts.FileSystemEntries {

src/harness/virtualFileSystemWithWatch.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ interface Array<T> { length: number; [n: number]: T; }`
922922
});
923923
}
924924
return { directories, files };
925-
}, path => this.realpath(path));
925+
}, path => this.realpath(path), path => this.directoryExists(path));
926926
}
927927

928928
createHash(s: string): string {

0 commit comments

Comments
 (0)