Change:
This was nicely uncovered by our internally implements a logic that throws an error in case multiple calls are made in parallel and a folder was created in the meantime. This is due to the fact that throws when a directory already exists. However, node's own implementation does not throw with the recurse option set to . We should align our implementation and not throw when a folder already exists.
Verification: run our smoke test and see how the hot-exit tests succeed.

Discussion:
// Create directories as needed for (let i = directoriesToCreate.length - 1; i >= 0; i--) { directory = joinPath(directory, directoriesToCreate[i]); <del> await provider.mkdir(directory); </del> <ins> try { await provider.mkdir(directory); } catch (error) { if (toFileSystemProviderErrorCode(error) !== FileSystemProviderErrorCode.FileExists) { // For mkdirp() we tolerate that the mkdir() call fails // in case the folder already exists. This follows node.js // own implementation of fs.mkdir({ recursive: true }) and // reduces the chances of race conditions leading to errors // if multiple calls try to create the same folders // As such, we only throw an error here if it is other than // the fact that the file already exists. // (see also https://github.com/microsoft/vscode/issues/89834) throw error; } } </ins> } }

import { NullLogService } from 'vs/platform/log/common/log'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { DisposableStore } from 'vs/base/common/lifecycle'; <del> import { isEqual } from 'vs/base/common/resources'; </del> <ins> import { isEqual, joinPath } from 'vs/base/common/resources'; </ins> import { VSBuffer, VSBufferReadable, streamToBufferReadableStream, VSBufferReadableStream, bufferToReadable, bufferToStream, streamToBuffer } from 'vs/base/common/buffer'; import { find } from 'vs/base/common/arrays';

assert.ok(!error); }); <ins> test('writeFile - no error when writing to same non-existing folder multiple times different new files', async () => { const newFolder = URI.file(join(testDir, 'some', 'new', 'folder')); const file1 = joinPath(newFolder, 'file-1'); const file2 = joinPath(newFolder, 'file-2'); const file3 = joinPath(newFolder, 'file-3'); // this essentially verifies that the mkdirp logic implemented // in the file service is able to receive multiple requests for // the same folder and will not throw errors if another racing // call succeeded first. const newContent = 'Updates to the small file'; await Promise.all([ service.writeFile(file1, VSBuffer.fromString(newContent)), service.writeFile(file2, VSBuffer.fromString(newContent)), service.writeFile(file3, VSBuffer.fromString(newContent)) ]); assert.ok(service.exists(file1)); assert.ok(service.exists(file2)); assert.ok(service.exists(file3)); }); test('writeFile - error when writing to folder that is a file', async () => { const existingFile = URI.file(join(testDir, 'my-file')); await service.createFile(existingFile); const newFile = joinPath(existingFile, 'file-1'); let error; const newContent = 'Updates to the small file'; try { await service.writeFile(newFile, VSBuffer.fromString(newContent)); } catch (e) { error = e; } assert.ok(error); }); </ins> const runWatchTests = isLinux; (runWatchTests ? test : test.skip)('watch - file', done => {

await app.workbench.editors.newUntitledFile(); const untitled = 'Untitled-1'; <del> const textToTypeInUntitled = 'Hello, Untitled Code'; </del> <ins> const textToTypeInUntitled = untitled; </ins> await app.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled); const readmeMd = 'readme.md';

await stableApp.workbench.editors.newUntitledFile(); const untitled = 'Untitled-1'; <del> const textToTypeInUntitled = 'Hello, Untitled Code'; </del> <ins> const textToTypeInUntitled = untitled; </ins> await stableApp.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled); const readmeMd = 'readme.md';