diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 083c74124bd..706ebf4325d 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1745,4 +1745,18 @@ declare module 'vscode' { } //#endregion + + //#region https://github.com/microsoft/vscode/issues/90517 + + export interface FileSystemError { + /** + * A code that identifies this error. + * + * Possible values are names of errors, like [`FileNotFound`](#FileSystemError.FileNotFound), + * or `undefined` for an unspecified error. + */ + readonly code?: string; + } + + ////#endregion } diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index a721785d28c..ca30ef0d660 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -148,7 +148,16 @@ class ConsumerFileSystem implements vscode.FileSystem { } // file system error - throw new FileSystemError(err.message, err.name as files.FileSystemProviderErrorCode); + switch (err.name) { + case files.FileSystemProviderErrorCode.FileExists: throw FileSystemError.FileExists(err.message); + case files.FileSystemProviderErrorCode.FileNotFound: throw FileSystemError.FileNotFound(err.message); + case files.FileSystemProviderErrorCode.FileNotADirectory: throw FileSystemError.FileNotADirectory(err.message); + case files.FileSystemProviderErrorCode.FileIsADirectory: throw FileSystemError.FileIsADirectory(err.message); + case files.FileSystemProviderErrorCode.NoPermissions: throw FileSystemError.NoPermissions(err.message); + case files.FileSystemProviderErrorCode.Unavailable: throw FileSystemError.Unavailable(err.message); + + default: throw new FileSystemError(err.message, err.name as files.FileSystemProviderErrorCode); + } } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index e7810d7b6a3..0c62c89ad01 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2333,9 +2333,13 @@ export class FileSystemError extends Error { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.Unavailable, FileSystemError.Unavailable); } + readonly code?: string; + constructor(uriOrMessage?: string | URI, code: FileSystemProviderErrorCode = FileSystemProviderErrorCode.Unknown, terminator?: Function) { super(URI.isUri(uriOrMessage) ? uriOrMessage.toString(true) : uriOrMessage); + this.code = terminator?.name; + // mark the error as file system provider error so that // we can extract the error code on the receiving side markAsFileSystemProviderError(this, code); diff --git a/src/vs/workbench/services/log/common/keyValueLogProvider.ts b/src/vs/workbench/services/log/common/keyValueLogProvider.ts index 0db6b00da32..9180d49303e 100644 --- a/src/vs/workbench/services/log/common/keyValueLogProvider.ts +++ b/src/vs/workbench/services/log/common/keyValueLogProvider.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType, FileSystemProviderErrorCode } from 'vs/platform/files/common/files'; +import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType } from 'vs/platform/files/common/files'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -53,13 +53,13 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys size: 0 }; } - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotFound)); + return Promise.reject(FileSystemError.FileNotFound(resource)); } async readdir(resource: URI): Promise<[string, FileType][]> { const hasKey = await this.hasKey(resource.path); if (hasKey) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotADirectory)); + return Promise.reject(FileSystemError.FileNotADirectory(resource)); } const keys = await this.getAllKeys(); const files: Map = new Map(); @@ -79,7 +79,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys async readFile(resource: URI): Promise { const hasKey = await this.hasKey(resource.path); if (!hasKey) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotFound)); + return Promise.reject(FileSystemError.FileNotFound(resource)); } const value = await this.getValue(resource.path); return VSBuffer.fromString(value).buffer; @@ -90,7 +90,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys if (!hasKey) { const files = await this.readdir(resource); if (files.length) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileIsADirectory)); + return Promise.reject(FileSystemError.FileIsADirectory(resource)); } } await this.setValue(resource.path, VSBuffer.wrap(content).toString());