Skip to content

Commit 06c5e24

Browse files
authored
FileSystemProvider extension: throwing a FileSystemError in readFile does not report to user (#118173)
* files - address #118060 on master * improve the fix for cases where no error is thrown
1 parent 61feeef commit 06c5e24

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

src/vs/platform/files/common/fileService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ export class FileService extends Disposable implements IFileService {
546546
stream.end(VSBuffer.wrap(buffer));
547547
} catch (err) {
548548
stream.error(err);
549+
stream.end();
549550
}
550551
})();
551552

src/vs/platform/files/test/browser/fileService.test.ts

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
import * as assert from 'assert';
77
import { FileService } from 'vs/platform/files/common/fileService';
88
import { URI } from 'vs/base/common/uri';
9-
import { IFileSystemProviderRegistrationEvent, FileSystemProviderCapabilities, IFileSystemProviderCapabilitiesChangeEvent } from 'vs/platform/files/common/files';
9+
import { IFileSystemProviderRegistrationEvent, FileSystemProviderCapabilities, IFileSystemProviderCapabilitiesChangeEvent, FileOpenOptions, FileReadStreamOptions, IStat, FileType } from 'vs/platform/files/common/files';
1010
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
1111
import { NullLogService } from 'vs/platform/log/common/log';
1212
import { timeout } from 'vs/base/common/async';
1313
import { NullFileSystemProvider } from 'vs/platform/files/test/common/nullFileSystemProvider';
14+
import { consumeStream, newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream';
15+
import { CancellationToken } from 'vs/base/common/cancellation';
1416

1517
suite('File Service', () => {
1618

@@ -126,4 +128,82 @@ suite('File Service', () => {
126128

127129
service.dispose();
128130
});
131+
132+
test('error from readFile bubbles through (https://github.com/microsoft/vscode/issues/118060) - async', async () => {
133+
testReadErrorBubbles(true);
134+
});
135+
136+
test('error from readFile bubbles through (https://github.com/microsoft/vscode/issues/118060)', async () => {
137+
testReadErrorBubbles(false);
138+
});
139+
140+
async function testReadErrorBubbles(async: boolean) {
141+
const service = new FileService(new NullLogService());
142+
143+
const provider = new class extends NullFileSystemProvider {
144+
async stat(resource: URI): Promise<IStat> {
145+
return {
146+
mtime: Date.now(),
147+
ctime: Date.now(),
148+
size: 100,
149+
type: FileType.File
150+
};
151+
}
152+
153+
readFile(resource: URI): Promise<Uint8Array> {
154+
if (async) {
155+
return timeout(5).then(() => { throw new Error('failed'); });
156+
}
157+
158+
throw new Error('failed');
159+
}
160+
161+
open(resource: URI, opts: FileOpenOptions): Promise<number> {
162+
if (async) {
163+
return timeout(5).then(() => { throw new Error('failed'); });
164+
}
165+
166+
throw new Error('failed');
167+
}
168+
169+
readFileStream(resource: URI, opts: FileReadStreamOptions, token: CancellationToken): ReadableStreamEvents<Uint8Array> {
170+
if (async) {
171+
const stream = newWriteableStream<Uint8Array>(chunk => chunk[0]);
172+
timeout(5).then(() => stream.error(new Error('failed')));
173+
174+
return stream;
175+
176+
}
177+
178+
throw new Error('failed');
179+
}
180+
};
181+
182+
const disposable = service.registerProvider('test', provider);
183+
184+
for (const capabilities of [FileSystemProviderCapabilities.FileReadWrite, FileSystemProviderCapabilities.FileReadStream, FileSystemProviderCapabilities.FileOpenReadWriteClose]) {
185+
provider.setCapabilities(capabilities);
186+
187+
let e1;
188+
try {
189+
await service.readFile(URI.parse('test://foo/bar'));
190+
} catch (error) {
191+
e1 = error;
192+
}
193+
194+
assert.ok(e1);
195+
196+
let e2;
197+
try {
198+
const stream = await service.readFileStream(URI.parse('test://foo/bar'));
199+
await consumeStream(stream.value, chunk => chunk[0]);
200+
} catch (error) {
201+
e2 = error;
202+
}
203+
204+
assert.ok(e2);
205+
}
206+
207+
disposable.dispose();
208+
}
129209
});

0 commit comments

Comments
 (0)