Skip to content

Commit 515303e

Browse files
[codex] Preserve desktop user-data probe failures (#3304)
Co-authored-by: codex <codex@users.noreply.github.com>
1 parent 20734d4 commit 515303e

2 files changed

Lines changed: 57 additions & 6 deletions

File tree

apps/desktop/src/app/DesktopAppIdentity.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as Effect from "effect/Effect";
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>(
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>(
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", () => {
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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@ const AppPackageMetadata = Schema.Struct({
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> => {
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* () {
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);

0 commit comments

Comments
 (0)