files - provide access to stat object from not modified error
This commit is contained in:
parent
d5c73cc952
commit
466dd4e490
4 changed files with 28 additions and 9 deletions
|
@ -6,7 +6,7 @@
|
|||
import { localize } from 'vs/nls';
|
||||
import { mark } from 'vs/base/common/performance';
|
||||
import { Disposable, IDisposable, toDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, IWriteFileOptions, IReadFileOptions, IFileStreamContent, IFileContent, ETAG_DISABLED, hasFileReadStreamCapability, IFileSystemProviderWithFileReadStreamCapability, ensureFileSystemProviderError, IFileSystemProviderCapabilitiesChangeEvent, IReadFileStreamOptions, FileDeleteOptions, FilePermission } from 'vs/platform/files/common/files';
|
||||
import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, IWriteFileOptions, IReadFileOptions, IFileStreamContent, IFileContent, ETAG_DISABLED, hasFileReadStreamCapability, IFileSystemProviderWithFileReadStreamCapability, ensureFileSystemProviderError, IFileSystemProviderCapabilitiesChangeEvent, IReadFileStreamOptions, FileDeleteOptions, FilePermission, NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IExtUri, extUri, extUriIgnorePathCase, isAbsolutePath } from 'vs/base/common/resources';
|
||||
|
@ -530,7 +530,14 @@ export class FileService extends Disposable implements IFileService {
|
|||
await consumeStream(fileStream);
|
||||
}
|
||||
|
||||
throw new FileOperationError(localize('err.read', "Unable to read file '{0}' ({1})", this.resourceForError(resource), ensureFileSystemProviderError(error).toString()), toFileOperationResult(error), options);
|
||||
// Re-throw errors as file operation errors but preserve
|
||||
// specific errors (such as not modified since)
|
||||
const message = localize('err.read', "Unable to read file '{0}' ({1})", this.resourceForError(resource), ensureFileSystemProviderError(error).toString());
|
||||
if (error instanceof NotModifiedSinceFileOperationError) {
|
||||
throw new NotModifiedSinceFileOperationError(message, error.stat, options);
|
||||
} else {
|
||||
throw new FileOperationError(message, toFileOperationResult(error), options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +605,7 @@ export class FileService extends Disposable implements IFileService {
|
|||
|
||||
// Throw if file not modified since (unless disabled)
|
||||
if (options && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED && options.etag === stat.etag) {
|
||||
throw new FileOperationError(localize('fileNotModifiedError', "File not modified since"), FileOperationResult.FILE_NOT_MODIFIED_SINCE, options);
|
||||
throw new NotModifiedSinceFileOperationError(localize('fileNotModifiedError', "File not modified since"), stat, options);
|
||||
}
|
||||
|
||||
// Throw if file is too large to load
|
||||
|
|
|
@ -11,7 +11,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
|
|||
import { Event } from 'vs/base/common/event';
|
||||
import { startsWithIgnoreCase } from 'vs/base/common/strings';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { isNumber, isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { isNumber } from 'vs/base/common/types';
|
||||
import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
|
||||
import { ReadableStreamEvents } from 'vs/base/common/stream';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
@ -1038,12 +1038,23 @@ export interface ICreateFileOptions {
|
|||
}
|
||||
|
||||
export class FileOperationError extends Error {
|
||||
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IReadFileOptions & IWriteFileOptions & ICreateFileOptions) {
|
||||
constructor(
|
||||
message: string,
|
||||
readonly fileOperationResult: FileOperationResult,
|
||||
readonly options?: IReadFileOptions & IWriteFileOptions & ICreateFileOptions
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
static isFileOperationError(obj: unknown): obj is FileOperationError {
|
||||
return obj instanceof Error && !isUndefinedOrNull((obj as FileOperationError).fileOperationResult);
|
||||
export class NotModifiedSinceFileOperationError extends FileOperationError {
|
||||
|
||||
constructor(
|
||||
message: string,
|
||||
readonly stat: IFileStatWithMetadata,
|
||||
options?: IReadFileOptions
|
||||
) {
|
||||
super(message, FileOperationResult.FILE_NOT_MODIFIED_SINCE, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { join, basename, dirname, posix } from 'vs/base/common/path';
|
|||
import { copy, Promises, rimraf, rimrafSync } from 'vs/base/node/pfs';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { existsSync, statSync, readdirSync, readFileSync, writeFileSync, renameSync, unlinkSync, mkdirSync, createReadStream } from 'fs';
|
||||
import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, FileSystemProviderCapabilities, FileChangeType, IFileChange, FileChangesEvent, FileOperationError, etag, IStat, IFileStatWithMetadata, IReadFileOptions, FilePermission } from 'vs/platform/files/common/files';
|
||||
import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, FileSystemProviderCapabilities, FileChangeType, IFileChange, FileChangesEvent, FileOperationError, etag, IStat, IFileStatWithMetadata, IReadFileOptions, FilePermission, NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { isLinux, isWindows } from 'vs/base/common/platform';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
|
@ -1491,6 +1491,7 @@ flakySuite('Disk File Service', function () {
|
|||
|
||||
assert.ok(error);
|
||||
assert.strictEqual(error!.fileOperationResult, FileOperationResult.FILE_NOT_MODIFIED_SINCE);
|
||||
assert.ok(error instanceof NotModifiedSinceFileOperationError && error.stat);
|
||||
assert.strictEqual(fileProvider.totalBytesRead, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -851,8 +851,8 @@ export class TestFileService implements IFileService {
|
|||
fireFileChanges(event: FileChangesEvent): void { this._onDidFilesChange.fire(event); }
|
||||
get onDidRunOperation(): Event<FileOperationEvent> { return this._onDidRunOperation.event; }
|
||||
fireAfterOperation(event: FileOperationEvent): void { this._onDidRunOperation.fire(event); }
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat>;
|
||||
resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise<IFileStatWithMetadata>;
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat>;
|
||||
resolve(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat> {
|
||||
return Promise.resolve({
|
||||
resource,
|
||||
|
|
Loading…
Reference in a new issue