History

[codex] Preserve desktop user-data probe failures (#3304)

Julius Marminge committed 4 months ago

Commit 515303e1 parent 20734d42 files · +57 −6Browse files

Unified · Split

2 files
  1. apps/desktop/src/app/DesktopAppIdentity.test.ts +34 −1
  2. apps/desktop/src/app/DesktopAppIdentity.ts +23 −5
apps/desktop/src/app/DesktopAppIdentity.test.ts+34−1
@@ -4,6 +4,7 @@ import * as Effect from "effect/Effect"; · 3 unmodified lines
44 import * as FileSystem from "effect/FileSystem";
55 import * as Layer from "effect/Layer";
66 import * as Option from "effect/Option";
7+import * as PlatformError from "effect/PlatformError";
78
89 import type * as Electron from "electron";
910
@@ -105,6 +106,7 @@ const withIdentity = <A, E, R>( · 95 unmodified lines
105106 readonly calls?: ElectronAppCalls;
106107 readonly environment?: TestEnvironmentInput;
107108 readonly legacyPathExists?: boolean;
109+ readonly legacyPathProbeError?: PlatformError.PlatformError;
108110 readonly packageJson?: string;
109111 readonly pngIconPath?: Option.Option<string>;
110112 } = {},
@@ -121,7 +123,11 @@ const withIdentity = <A, E, R>( · 10 unmodified lines
121123 Layer.provideMerge(
122124 FileSystem.layerNoop({
123125 exists: (path) =>
124− Effect.succeed(input.legacyPathExists === true && path.includes("T3 Code (Alpha)")),
126+ input.legacyPathProbeError
127+ ? Effect.fail(input.legacyPathProbeError)
128+ : Effect.succeed(
129+ input.legacyPathExists === true && path.includes("T3 Code (Alpha)"),
130+ ),
125131 readFileString: () =>
126132 Effect.succeed(input.packageJson ?? '{"t3codeCommitHash":"abcdef1234567890"}'),
127133 }),
@@ -147,6 +153,33 @@ describe("DesktopAppIdentity", () => { · 19 unmodified lines
147153 ),
148154 );
149155
156+ it.effect("preserves failures while inspecting the legacy userData path", () => {
157+ const legacyPath = "/Users/alice/Library/Application Support/T3 Code (Alpha)";
158+ const cause = PlatformError.systemError({
159+ _tag: "PermissionDenied",
160+ module: "FileSystem",
161+ method: "exists",
162+ description: "permission denied",
163+ pathOrDescriptor: legacyPath,
164+ });
165+
166+ return withIdentity(
167+ Effect.gen(function* () {
168+ const identity = yield* DesktopAppIdentity.DesktopAppIdentity;
169+ const error = yield* identity.resolveUserDataPath.pipe(Effect.flip);
170+
171+ assert.instanceOf(error, DesktopAppIdentity.DesktopUserDataPathResolutionError);
172+ assert.equal(error.legacyPath, legacyPath);
173+ assert.strictEqual(error.cause, cause);
174+ assert.equal(
175+ error.message,
176+ `Failed to inspect legacy desktop user-data path at "${legacyPath}".`,
177+ );
178+ }),
179+ { legacyPathProbeError: cause },
180+ );
181+ });
182+
150183 it.effect("configures app identity from the environment commit override", () => {
151184 const calls: ElectronAppCalls = {
152185 setAboutPanelOptions: [],
apps/desktop/src/app/DesktopAppIdentity.ts+23−5
@@ -18,10 +18,22 @@ const AppPackageMetadata = Schema.Struct({ · 17 unmodified lines
1818 });
1919 const decodeAppPackageMetadata = Schema.decodeEffect(Schema.fromJsonString(AppPackageMetadata));
2020
21+export class DesktopUserDataPathResolutionError extends Schema.TaggedErrorClass<DesktopUserDataPathResolutionError>()(
22+ "DesktopUserDataPathResolutionError",
23+ {
24+ legacyPath: Schema.String,
25+ cause: Schema.Defect(),
26+ },
27+) {
28+ override get message(): string {
29+ return `Failed to inspect legacy desktop user-data path at "${this.legacyPath}".`;
30+ }
31+}
32+
2133 export class DesktopAppIdentity extends Context.Service<
2234 DesktopAppIdentity,
2335 {
24− readonly resolveUserDataPath: Effect.Effect<string>;
36+ readonly resolveUserDataPath: Effect.Effect<string, DesktopUserDataPathResolutionError>;
2537 readonly configure: Effect.Effect<void>;
2638 }
2739 >()("@t3tools/desktop/app/DesktopAppIdentity") {}
@@ -33,7 +45,7 @@ const normalizeCommitHash = (value: string): Option.Option<string> => { · 5 unmodified lines
3345 : Option.none();
3446 };
3547
36−const make = Effect.gen(function* () {
48+export const make = Effect.gen(function* () {
3749 const assets = yield* DesktopAssets.DesktopAssets;
3850 const electronApp = yield* ElectronApp.ElectronApp;
3951 const environment = yield* DesktopEnvironment.DesktopEnvironment;
@@ -83,9 +95,15 @@ const make = Effect.gen(function* () { · 43 unmodified lines
8395 environment.appDataDirectory,
8496 environment.legacyUserDataDirName,
8597 );
86− const legacyPathExists = yield* fileSystem
87− .exists(legacyPath)
88− .pipe(Effect.orElseSucceed(() => false));
98+ const legacyPathExists = yield* fileSystem.exists(legacyPath).pipe(
99+ Effect.mapError(
100+ (cause) =>
101+ new DesktopUserDataPathResolutionError({
102+ legacyPath,
103+ cause,
104+ }),
105+ ),
106+ );
89107 return legacyPathExists
90108 ? legacyPath
91109 : environment.path.join(environment.appDataDirectory, environment.userDataDirName);