src/vs/workbench/api/browser/mainThreadUriOpeners.ts/MainThreadUriOpeners/createOpener
class MainThreadUriOpeners:	private createOpener(id: string, metadata: RegisteredOpenerMetadata): IExternalUriOpener {
		return {
			id: id,
			label: metadata.label,
			canOpen: (uri, token) => {
				return this.proxy.$canOpenUri(id, uri, token);
			},
			openExternalUri: async (uri, ctx, token) => {
				try {
					await this.proxy.$openUri(id, { resolvedUri: uri, sourceUri: ctx.sourceUri }, token);
				} catch (e) {
					if (!isPromiseCanceledError(e)) {
						const openDefaultAction = new Action('default', localize('openerFailedUseDefault', "Open using default opener"), undefined, undefined, async () => {
							await this.openerService.open(uri, {
								allowTunneling: false,
								allowContributedOpeners: defaultExternalUriOpenerId,
							});
						});
						openDefaultAction.tooltip = uri.toString();

						this.notificationService.notify({
							severity: Severity.Error,
							message: localize({
								key: 'openerFailedMessage',
								comment: ['{0} is the id of the opener. {1} is the url being opened.'],
							}, 'Could not open uri with \'{0}\': {1}', id, e.toString()),
							actions: {
								primary: [
									openDefaultAction
								]
							}
						});
					}
				}
				return true;
			},
		};
	}