diff --git a/apps/desktop/src/settings/DesktopClientSettings.test.ts b/apps/desktop/src/settings/DesktopClientSettings.test.ts index 2d1d7fc547da3e077c4405cd822d63400335e3ae..3584d6a21e426ffef1a879689536beecd5559e0a 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.test.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.test.ts @@ -5,6 +5,7 @@ import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; import * as Option from "effect/Option"; +import * as PlatformError from "effect/PlatformError"; import * as Schema from "effect/Schema"; import * as DesktopConfig from "../app/DesktopConfig.ts"; @@ -117,11 +118,13 @@ describe("DesktopClientSettings", () => { assert.instanceOf(error, DesktopClientSettings.DesktopClientSettingsWriteError); assert.equal(error.operation, "replace-settings-file"); assert.equal(error.path, environment.clientSettingsPath); - assert.exists(error.cause); + assert.instanceOf(error.cause, PlatformError.PlatformError); + assert.isString(error.cause.stack); assert.equal( error.message, `Desktop client settings write failed during replace-settings-file at ${environment.clientSettingsPath}.`, ); + assert.notInclude(error.message, error.cause.message); }), ), ); diff --git a/apps/desktop/src/settings/DesktopClientSettings.ts b/apps/desktop/src/settings/DesktopClientSettings.ts index 585397d7502c69328e4d199821e4409b38e2837c..d08184f4ab76f1bd3a72f672b54c3b62ec0edea8 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.ts @@ -25,7 +25,9 @@ const decodeClientSettingsJsonValue = Schema.decodeEffect(ClientSettingsJson); const decodeClientSettingsJson = (raw: string): Effect.Effect => decodeLegacyClientSettingsDocumentJson(raw).pipe( Effect.map((document) => document.settings), - Effect.catch(() => decodeClientSettingsJsonValue(raw)), + Effect.catchTags({ + SchemaError: () => decodeClientSettingsJsonValue(raw), + }), ); const encodeClientSettingsJson = Schema.encodeEffect(ClientSettingsJson); @@ -36,7 +38,6 @@ const DesktopClientSettingsWriteOperation = Schema.Literals([ "write-temporary-file", "replace-settings-file", ]); -type DesktopClientSettingsWriteOperation = typeof DesktopClientSettingsWriteOperation.Type; export class DesktopClientSettingsWriteError extends Schema.TaggedErrorClass()( "DesktopClientSettingsWriteError", @@ -51,13 +52,6 @@ export class DesktopClientSettingsWriteError extends Schema.TaggedErrorClass - new DesktopClientSettingsWriteError({ operation, path, cause }); - export class DesktopClientSettings extends Context.Service< DesktopClientSettings, { @@ -96,19 +90,45 @@ const writeClientSettings = Effect.fnUntraced(function* (input: { const directory = input.path.dirname(input.settingsPath); const tempPath = `${input.settingsPath}.${process.pid}.${input.suffix}.tmp`; const encoded = yield* encodeClientSettingsJson(input.settings).pipe( - Effect.mapError((cause) => writeError("encode-document", input.settingsPath, cause)), - ); - yield* input.fileSystem - .makeDirectory(directory, { recursive: true }) - .pipe(Effect.mapError((cause) => writeError("create-directory", directory, cause))); - yield* input.fileSystem - .writeFileString(tempPath, `${encoded}\n`) - .pipe(Effect.mapError((cause) => writeError("write-temporary-file", tempPath, cause))); - yield* input.fileSystem - .rename(tempPath, input.settingsPath) - .pipe( - Effect.mapError((cause) => writeError("replace-settings-file", input.settingsPath, cause)), - ); + Effect.mapError( + (cause) => + new DesktopClientSettingsWriteError({ + operation: "encode-document", + path: input.settingsPath, + cause, + }), + ), + ); + yield* input.fileSystem.makeDirectory(directory, { recursive: true }).pipe( + Effect.mapError( + (cause) => + new DesktopClientSettingsWriteError({ + operation: "create-directory", + path: directory, + cause, + }), + ), + ); + yield* input.fileSystem.writeFileString(tempPath, `${encoded}\n`).pipe( + Effect.mapError( + (cause) => + new DesktopClientSettingsWriteError({ + operation: "write-temporary-file", + path: tempPath, + cause, + }), + ), + ); + yield* input.fileSystem.rename(tempPath, input.settingsPath).pipe( + Effect.mapError( + (cause) => + new DesktopClientSettingsWriteError({ + operation: "replace-settings-file", + path: input.settingsPath, + cause, + }), + ), + ); }); export const make = Effect.gen(function* () { @@ -124,8 +144,13 @@ export const make = Effect.gen(function* () { set: (settings) => crypto.randomUUIDv4.pipe( Effect.map((uuid) => uuid.replace(/-/g, "")), - Effect.mapError((cause) => - writeError("create-temporary-file-name", environment.clientSettingsPath, cause), + Effect.mapError( + (cause) => + new DesktopClientSettingsWriteError({ + operation: "create-temporary-file-name", + path: environment.clientSettingsPath, + cause, + }), ), Effect.flatMap((suffix) => writeClientSettings({