Skip to content

Commit a054290

Browse files
Merge pull request #2529 from github/robertbrignull/queries-panel-errors
Ensure errors for one path don't stop discovery of other paths
2 parents c628454 + 7135d39 commit a054290

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-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: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
getOnDiskWorkspaceFolders,
1717
getOnDiskWorkspaceFoldersObjects,
1818
} from "./workspace-folders";
19+
import { getErrorMessage } from "../../pure/helpers-pure";
1920

2021
interface PathData {
2122
path: string;
@@ -152,9 +153,21 @@ export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
152153
protected async discover() {
153154
let pathsUpdated = false;
154155
for (const path of this.changedFilePaths) {
155-
this.changedFilePaths.delete(path);
156-
if (await this.handleChangedPath(path)) {
157-
pathsUpdated = true;
156+
try {
157+
this.changedFilePaths.delete(path);
158+
if (await this.handleChangedPath(path)) {
159+
pathsUpdated = true;
160+
}
161+
} catch (e) {
162+
// If we get an error while processing a path, just log it and continue.
163+
// There aren't any network operations happening here or anything else
164+
// that's likely to succeed on a retry, so don't bother adding it back
165+
// to the changedFilePaths set.
166+
void extLogger.log(
167+
`${
168+
this.name
169+
} failed while processing path "${path}": ${getErrorMessage(e)}`,
170+
);
158171
}
159172
}
160173

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ 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";
15+
import { getErrorMessage } from "../../../../../src/pure/helpers-pure";
1416

1517
interface TestData {
1618
path: string;
@@ -21,6 +23,9 @@ interface TestData {
2123
* A test FilePathDiscovery that operates on files with the ".test" extension.
2224
*/
2325
class TestFilePathDiscovery extends FilePathDiscovery<TestData> {
26+
public getDataForPathFunc: ((path: string) => Promise<TestData>) | undefined =
27+
undefined;
28+
2429
constructor() {
2530
super("TestFilePathDiscovery", "**/*.test");
2631
}
@@ -34,6 +39,9 @@ class TestFilePathDiscovery extends FilePathDiscovery<TestData> {
3439
}
3540

3641
protected async getDataForPath(path: string): Promise<TestData> {
42+
if (this.getDataForPathFunc !== undefined) {
43+
return this.getDataForPathFunc(path);
44+
}
3745
return {
3846
path,
3947
contents: readFileSync(path, "utf8"),
@@ -353,6 +361,39 @@ describe("FilePathDiscovery", () => {
353361
});
354362
});
355363

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

0 commit comments

Comments
 (0)