diff --git a/packages/core/src/workspace/environment.ts b/packages/core/src/workspace/environment.ts index 9e65e9c52c..64e8f8588f 100644 --- a/packages/core/src/workspace/environment.ts +++ b/packages/core/src/workspace/environment.ts @@ -18,6 +18,24 @@ export class NotFoundError extends Schema.TaggedErrorClass()("Wor path: Schema.String, }) {} +/** + * Wrap one driver promise, translating the driver's not-found signal into the + * environment error vocabulary so drivers and fakes never construct it ad hoc. + */ +export const tryOperation = (input: { + readonly operation: string + readonly path: string + readonly run: () => Promise + readonly isNotFound: (cause: unknown) => boolean +}): Effect.Effect => + Effect.tryPromise({ + try: input.run, + catch: (cause) => + input.isNotFound(cause) + ? new NotFoundError({ path: input.path }) + : new Error({ operation: input.operation, path: input.path, cause }), + }) + export interface FileInfo { readonly type: FileSystem.File.Type } diff --git a/packages/core/test/lib/workspace.ts b/packages/core/test/lib/workspace.ts index c66b69a621..86c7e8edf1 100644 --- a/packages/core/test/lib/workspace.ts +++ b/packages/core/test/lib/workspace.ts @@ -39,12 +39,11 @@ export const directoryEnvironment = ( spawn: ChildProcessSpawner["Service"]["spawn"], ): WorkspaceEnvironment.Interface => { const wrap = (operation: string, path: string, run: () => Promise) => - Effect.tryPromise({ - try: run, - catch: (cause) => - (cause as NodeJS.ErrnoException).code === "ENOENT" - ? new WorkspaceEnvironment.NotFoundError({ path }) - : new WorkspaceEnvironment.Error({ operation, path, cause }), + WorkspaceEnvironment.tryOperation({ + operation, + path, + run, + isNotFound: (cause) => (cause as NodeJS.ErrnoException).code === "ENOENT", }) return WorkspaceEnvironment.make({ directory: root, diff --git a/packages/server/src/workspace/modal.ts b/packages/server/src/workspace/modal.ts index f1b2debe1a..9f2e7bcac1 100644 --- a/packages/server/src/workspace/modal.ts +++ b/packages/server/src/workspace/modal.ts @@ -95,12 +95,11 @@ const FILE_TYPE = { file: "File", directory: "Directory", symlink: "SymbolicLink const files = (sandbox: Sandbox): WorkspaceEnvironment.Files => { const wrap = (operation: string, path: string, run: () => Promise) => - Effect.tryPromise({ - try: run, - catch: (cause) => - cause instanceof SandboxFilesystemNotFoundError - ? new WorkspaceEnvironment.NotFoundError({ path }) - : new WorkspaceEnvironment.Error({ operation, path, cause }), + WorkspaceEnvironment.tryOperation({ + operation, + path, + run, + isNotFound: (cause) => cause instanceof SandboxFilesystemNotFoundError, }) return { stat: (path) =>