diff --git a/packages/core/src/profile/config.ts b/packages/core/src/profile/config.ts index cd85d7d1..cdd87682 100644 --- a/packages/core/src/profile/config.ts +++ b/packages/core/src/profile/config.ts @@ -58,6 +58,12 @@ const listPersistence = ({ localDir }: { localDir: string }) => { } } +export class ProfileLoadError extends Error { + constructor(message: string) { + super(message) + } +} + export const localProfilesConfig = ( localDir: string, fsFromUrl: (url: string, baseDir: string) => Promise, @@ -74,7 +80,7 @@ export const localProfilesConfig = ( async function get(alias: string | undefined, opts?: { throwOnNotFound: boolean }): Promise { const throwOrUndefined = () => { if (opts?.throwOnNotFound) { - throw new Error(`Profile ${alias} not found`) + throw new ProfileLoadError(`Profile ${alias} not found`) } return undefined } @@ -82,14 +88,23 @@ export const localProfilesConfig = ( const { profiles, current } = await listP.read() const aliasToGet = alias ?? current if (!aliasToGet) { - return throwOrUndefined() + if (opts?.throwOnNotFound) { + throw new ProfileLoadError('Profile not specified and no current profile is set') + } + return undefined } const locationUrl = profiles[aliasToGet]?.location if (!locationUrl) { + if (opts?.throwOnNotFound) { + throw new ProfileLoadError(`No profile with alias ${aliasToGet}`) + } return throwOrUndefined() } const tarSnapshotStore = await storeFromUrl(locationUrl) - const profileInfo = await profileStore(tarSnapshotStore).ref.info() + const profileInfo = await profileStore(tarSnapshotStore).ref.info({ throwOnNotFound: false }) + if (!profileInfo) { + throw new ProfileLoadError(`Could not load profile "${aliasToGet}" at ${locationUrl}. The profile may have been deleted`) + } return { alias: aliasToGet, location: locationUrl, @@ -200,7 +215,10 @@ export const localProfilesConfig = ( throw new Error(`Profile ${alias} already exists`) } const tarSnapshotStore = await storeFromUrl(fromLocation) - const info = await profileStore(tarSnapshotStore).ref.info() + const info = await profileStore(tarSnapshotStore).ref.info({ throwOnNotFound: false }) + if (!info) { + throw new Error(`Cannot import profile from ${fromLocation}. The profile may have been deleted`) + } const newProfile = { id: info.id, alias, diff --git a/packages/core/src/profile/store.ts b/packages/core/src/profile/store.ts index f4092102..63ee12bc 100644 --- a/packages/core/src/profile/store.ts +++ b/packages/core/src/profile/store.ts @@ -27,7 +27,14 @@ const readLines = (buffer: Buffer | undefined) => { const profileReader = (reader: FsReader) => { const { readJsonOrThrow, readJSON } = jsonReader(reader) - const info = async () => await readJsonOrThrow(filenames.info) + async function info(opts: { throwOnNotFound: false }): Promise + async function info(opts: { throwOnNotFound: true }): Promise + async function info(): Promise + async function info( + { throwOnNotFound = true }: { throwOnNotFound?: boolean } = { throwOnNotFound: true }, + ): Promise { + return await (throwOnNotFound ? readJsonOrThrow : readJSON)(filenames.info) + } return { info, driver: async () => (await info()).driver,