Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Ignore errors in listdir() from getFileType().
  • Loading branch information
ericsnowcurrently committed Feb 10, 2020
commit cb671004a3d3fa9b0eda5cc276dbe47be8ff13f9
13 changes: 10 additions & 3 deletions src/client/common/platform/fileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { injectable } from 'inversify';
import { promisify } from 'util';
import * as vscode from 'vscode';
import '../../common/extensions';
import { traceError } from '../logger';
import { createDeferred } from '../utils/async';
import { isFileNotFoundError, isNoPermissionsError } from './errors';
import { FileSystemPaths, FileSystemPathUtils } from './fs-paths';
Expand Down Expand Up @@ -213,9 +214,15 @@ export class RawFileSystem implements IRawFileSystem {
const files = await this.fsExtra.readdir(dirname);
const promises = files.map(async basename => {
const filename = this.paths.join(dirname, basename);
// Note that this follows symlinks (while still preserving
// the Symlink flag).
const fileType = await this.getFileType(filename);
let fileType: FileType;
try {
// Note that getFileType() follows symlinks (while still
// preserving the Symlink flag).
fileType = await this.getFileType(filename);
} catch (err) {
traceError(`failure while getting file type for "${filename}"`, err);
fileType = FileType.Unknown;
}
return [filename, fileType] as [string, FileType];
});
return Promise.all(promises);
Expand Down
25 changes: 25 additions & 0 deletions src/test/common/platform/filesystem.functional.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,31 @@ suite('FileSystem - raw', () => {

await expect(promise).to.eventually.be.rejected;
});

test('ignores errors from getFileType()', async function() {
if (WINDOWS) {
// tslint:disable-next-line:no-invalid-this
this.skip();
}
const dirname = await fix.createDirectory('x/y/z');
const file1 = await fix.createFile('x/y/z/__init__.py', '');
const file2 = await fix.createFile('x/y/z/spam.py', '...');
const file3 = await fix.createFile('x/y/z/eggs.py', '...');
await fs.chmod(dirname, 0o400);

let entries: [string, FileType][];
try {
entries = await fileSystem.listdir(dirname);
} finally {
await fs.chmod(dirname, 0o755);
}

expect(entries.sort()).to.deep.equal([
[file1, FileType.Unknown],
[file3, FileType.Unknown],
[file2, FileType.Unknown]
]);
});
});

// non-async
Expand Down
32 changes: 32 additions & 0 deletions src/test/common/platform/filesystem.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,38 @@ suite('Raw FileSystem', () => {
await expect(promise).to.eventually.be.rejected;
verifyAll();
});

test('ignores errors from getFileType()', async () => {
const dirname = 'x/y/z';
const names = [
// These match the items in "expected".
'__init__.py',
'spam.py',
'eggs.py'
];
const expected: [string, FileType][] = [
['x/y/z/__init__.py', FileType.File],
['x/y/z/spam.py', FileType.File],
['x/y/z/eggs.py', FileType.Unknown]
];
raw.setup(r => r.readdir(dirname)) // expect the specific filename
.returns(() => Promise.resolve(names));
names.forEach((name, i) => {
const [filename, filetype] = expected[i];
raw.setup(r => r.join(dirname, name)) // expect the specific filename
.returns(() => filename);
if (filetype === FileType.Unknown) {
raw.setup(r => r.lstat(filename)) // expect the specific filename
.throws(new Error('oops!'));
} else {
setupForFileType(filename, filetype);
}
});

const entries = await filesystem.listdir(dirname);

expect(entries.sort()).to.deep.equal(expected.sort());
});
});

suite('readTextSync', () => {
Expand Down