Skip to content

Commit fa773a0

Browse files
Ensure errors for one path don't stop discovery of other paths
1 parent 2c97ca9 commit fa773a0

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

extensions/ql-vscode/src/common/discovery.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export abstract class Discovery extends DisposableObject {
1111
private restartWhenFinished = false;
1212
private currentDiscoveryPromise: Promise<void> | undefined;
1313

14-
constructor(private readonly name: string, private readonly logger: Logger) {
14+
constructor(
15+
protected readonly name: string,
16+
private readonly logger: Logger,
17+
) {
1518
super();
1619
}
1720

extensions/ql-vscode/src/common/vscode/file-path-discovery.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,19 @@ export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
152152
protected async discover() {
153153
let pathsUpdated = false;
154154
for (const path of this.changedFilePaths) {
155-
this.changedFilePaths.delete(path);
156-
if (await this.handleChangedPath(path)) {
157-
pathsUpdated = true;
155+
try {
156+
this.changedFilePaths.delete(path);
157+
if (await this.handleChangedPath(path)) {
158+
pathsUpdated = true;
159+
}
160+
} catch (e) {
161+
// If we get an error while processing a path, just log it and continue.
162+
// There aren't any network operations happening here or anything else
163+
// that's likely to succeed on a retry, so don't bother adding it back
164+
// to the changedFilePaths set.
165+
void extLogger.log(
166+
`${this.name} failed while processing path: ${path}`,
167+
);
158168
}
159169
}
160170

extensions/ql-vscode/test/vscode-tests/minimal-workspace/common/vscode/file-path-discovery.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { basename, dirname, join } from "path";
1111
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
1212
import * as tmp from "tmp";
1313
import { normalizePath } from "../../../../../src/pure/files";
14+
import { extLogger } from "../../../../../src/common/logging/vscode/loggers";
1415

1516
interface TestData {
1617
path: string;
@@ -21,6 +22,9 @@ interface TestData {
2122
* A test FilePathDiscovery that operates on files with the ".test" extension.
2223
*/
2324
class TestFilePathDiscovery extends FilePathDiscovery<TestData> {
25+
public getDataForPathFunc: ((path: string) => Promise<TestData>) | undefined =
26+
undefined;
27+
2428
constructor() {
2529
super("TestFilePathDiscovery", "**/*.test");
2630
}
@@ -34,6 +38,9 @@ class TestFilePathDiscovery extends FilePathDiscovery<TestData> {
3438
}
3539

3640
protected async getDataForPath(path: string): Promise<TestData> {
41+
if (this.getDataForPathFunc !== undefined) {
42+
return this.getDataForPathFunc(path);
43+
}
3744
return {
3845
path,
3946
contents: readFileSync(path, "utf8"),
@@ -353,6 +360,39 @@ describe("FilePathDiscovery", () => {
353360
});
354361
});
355362

363+
describe("error handling", () => {
364+
it("should handle errors and still process other files", async () => {
365+
await discovery.initialRefresh();
366+
367+
discovery.getDataForPathFunc = async (path: string) => {
368+
if (basename(path) === "123.test") {
369+
throw new Error("error");
370+
} else {
371+
return { path, contents: readFileSync(path, "utf8") };
372+
}
373+
};
374+
const logSpy = jest.spyOn(extLogger, "log");
375+
376+
makeTestFile(join(workspacePath, "123.test"));
377+
makeTestFile(join(workspacePath, "456.test"));
378+
379+
onDidCreateFile.fire(Uri.file(join(workspacePath, "123.test")));
380+
onDidCreateFile.fire(Uri.file(join(workspacePath, "456.test")));
381+
await discovery.waitForCurrentRefresh();
382+
383+
expect(new Set(discovery.getPathData())).toEqual(
384+
new Set([{ path: join(workspacePath, "456.test"), contents: "456" }]),
385+
);
386+
387+
expect(logSpy).toHaveBeenCalledWith(
388+
`TestFilePathDiscovery failed while processing path: ${join(
389+
workspacePath,
390+
"123.test",
391+
)}`,
392+
);
393+
});
394+
});
395+
356396
describe("workspaceFoldersChanged", () => {
357397
it("initialRefresh establishes watchers", async () => {
358398
await discovery.initialRefresh();

0 commit comments

Comments
 (0)