web - guard against exception thrown from picking file/folder when user cancels

This commit is contained in:
Benjamin Pasero 2021-08-11 13:43:09 +02:00
parent 1c1d04bc6f
commit a6cf57db06
No known key found for this signature in database
GPG key ID: E6380CC4C8219E65
3 changed files with 48 additions and 31 deletions

View file

@ -149,7 +149,7 @@ export abstract class AbstractFileDialogService implements IFileDialogService {
return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]);
}
protected async pickFileFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<any> {
protected async pickFileFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<void> {
const title = nls.localize('openFileOrFolder.title', 'Open File Or Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
@ -164,14 +164,14 @@ export abstract class AbstractFileDialogService implements IFileDialogService {
}
if (stat.isDirectory || options.forceNewWindow || preferNewWindow) {
return this.hostService.openWindow([toOpen], { forceNewWindow: options.forceNewWindow, remoteAuthority: options.remoteAuthority });
await this.hostService.openWindow([toOpen], { forceNewWindow: options.forceNewWindow, remoteAuthority: options.remoteAuthority });
} else {
return this.openerService.open(uri, { fromUserGesture: true, editorOptions: { pinned: true } });
await this.openerService.open(uri, { fromUserGesture: true, editorOptions: { pinned: true } });
}
}
}
protected async pickFileAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<any> {
protected async pickFileAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<void> {
const title = nls.localize('openFile.title', 'Open File');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
@ -180,9 +180,9 @@ export abstract class AbstractFileDialogService implements IFileDialogService {
this.addFileToRecentlyOpened(uri);
if (options.forceNewWindow || preferNewWindow) {
return this.hostService.openWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow, remoteAuthority: options.remoteAuthority });
await this.hostService.openWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow, remoteAuthority: options.remoteAuthority });
} else {
return this.openerService.open(uri, { fromUserGesture: true, editorOptions: { pinned: true } });
await this.openerService.open(uri, { fromUserGesture: true, editorOptions: { pinned: true } });
}
}
}
@ -195,7 +195,7 @@ export abstract class AbstractFileDialogService implements IFileDialogService {
}
}
protected async pickFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<any> {
protected async pickFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<void> {
const title = nls.localize('openFolder.title', 'Open Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
@ -205,7 +205,7 @@ export abstract class AbstractFileDialogService implements IFileDialogService {
}
}
protected async pickWorkspaceAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<any> {
protected async pickWorkspaceAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<void> {
const title = nls.localize('openWorkspace.title', 'Open Workspace');
const filters: FileFilter[] = [{ name: nls.localize('filterName.workspace', 'Workspace'), extensions: [WORKSPACE_EXTENSION] }];
const availableFileSystems = this.addFileSchemaIfNeeded(schema);

View file

@ -20,7 +20,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.fileService.getProvider(Schemas.file) as HTMLFileSystemProvider;
}
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
@ -34,7 +34,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
throw new Error(localize('pickFolderAndOpen', "Can't open folders, try adding a folder to the workspace instead."));
}
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
@ -45,14 +45,19 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.pickFileAndOpenSimplified(schema, options, false);
}
const [handle] = await window.showOpenFilePicker({ multiple: false });
let fileHandle: FileSystemHandle | undefined = undefined;
try {
([fileHandle] = await window.showOpenFilePicker({ multiple: false }));
} catch (error) {
return; // `showOpenFilePicker` will throw an error when the user cancels
}
const uri = this.fileSystemProvider.registerFileHandle(handle);
const uri = this.fileSystemProvider.registerFileHandle(fileHandle);
await this.openerService.open(uri, { fromUserGesture: true, editorOptions: { pinned: true } });
}
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
@ -89,9 +94,14 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.pickFileToSaveSimplified(schema, options);
}
const handle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters) });
let fileHandle: FileSystemHandle | undefined = undefined;
try {
fileHandle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters) });
} catch (error) {
return; // `showSaveFilePicker` will throw an error when the user cancels
}
return this.fileSystemProvider.registerFileHandle(handle);
return this.fileSystemProvider.registerFileHandle(fileHandle);
}
private getFilePickerTypes(filters?: FileFilter[]): FilePickerAcceptType[] | undefined {
@ -115,9 +125,14 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.showSaveDialogSimplified(schema, options);
}
const handle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters) });
let fileHandle: FileSystemHandle | undefined = undefined;
try {
fileHandle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters) });
} catch (error) {
return; // `showSaveFilePicker` will throw an error when the user cancels
}
return this.fileSystemProvider.registerFileHandle(handle);
return this.fileSystemProvider.registerFileHandle(fileHandle);
}
async showOpenDialog(options: IOpenDialogOptions): Promise<URI[] | undefined> {
@ -128,19 +143,21 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
}
let uri: URI | undefined;
if (options.canSelectFiles) {
const handle = await window.showOpenFilePicker({ multiple: false, types: this.getFilePickerTypes(options.filters) });
if (handle.length === 1) {
uri = this.fileSystemProvider.registerFileHandle(handle[0]);
try {
if (options.canSelectFiles) {
const handle = await window.showOpenFilePicker({ multiple: false, types: this.getFilePickerTypes(options.filters) });
if (handle.length === 1) {
uri = this.fileSystemProvider.registerFileHandle(handle[0]);
}
} else {
const handle = await window.showDirectoryPicker();
uri = this.fileSystemProvider.registerDirectoryHandle(handle);
}
} else {
const handle = await window.showDirectoryPicker();
uri = this.fileSystemProvider.registerDirectoryHandle(handle);
} catch (error) {
// ignore - `showOpenFilePicker` / `showDirectoryPicker` will throw an error when the user cancels
}
if (uri) {
return [uri];
}
return undefined;
return uri ? [uri] : undefined;
}
private shouldUseSimplified(scheme: string): boolean {

View file

@ -62,7 +62,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
};
}
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
@ -76,7 +76,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.nativeHostService.pickFileFolderAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
@ -90,7 +90,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.nativeHostService.pickFileAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {