Skip to content

Commit fccecd8

Browse files
[codex] Preserve detached desktop action causes (#3371)
Co-authored-by: codex <codex@users.noreply.github.com>
1 parent 30a084c commit fccecd8

3 files changed

Lines changed: 71 additions & 13 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { assert, describe, it } from "@effect/vitest";
2+
import * as Cause from "effect/Cause";
3+
4+
import { DesktopLifecycleRelaunchError } from "./DesktopLifecycle.ts";
5+
import { DesktopApplicationMenuActionError } from "../window/DesktopApplicationMenu.ts";
6+
7+
describe("desktop detached action errors", () => {
8+
it("preserves the complete relaunch failure cause and reason", () => {
9+
const cause = Cause.combine(
10+
Cause.fail(new Error("shutdown failed")),
11+
Cause.die(new Error("relaunch defect")),
12+
);
13+
const error = new DesktopLifecycleRelaunchError({
14+
reason: "apply update",
15+
cause,
16+
});
17+
18+
assert.strictEqual(error.cause, cause);
19+
assert.equal(error.reason, "apply update");
20+
assert.equal(error.message, 'Desktop relaunch failed for reason "apply update".');
21+
});
22+
23+
it("preserves the complete menu action failure cause and action", () => {
24+
const cause = Cause.combine(
25+
Cause.fail(new Error("window unavailable")),
26+
Cause.die(new Error("dispatch defect")),
27+
);
28+
const error = new DesktopApplicationMenuActionError({
29+
action: "open-settings",
30+
cause,
31+
});
32+
33+
assert.strictEqual(error.cause, cause);
34+
assert.equal(error.action, "open-settings");
35+
assert.equal(error.message, 'Desktop menu action "open-settings" failed.');
36+
});
37+
});

apps/desktop/src/app/DesktopLifecycle.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import * as Cause from "effect/Cause";
21
import * as Context from "effect/Context";
32
import * as Effect from "effect/Effect";
43
import * as Layer from "effect/Layer";
54
import * as Ref from "effect/Ref";
5+
import * as Schema from "effect/Schema";
66
import * as Scope from "effect/Scope";
77

88
import type * as Electron from "electron";
@@ -15,6 +15,18 @@ import * as ElectronTheme from "../electron/ElectronTheme.ts";
1515
import * as DesktopState from "./DesktopState.ts";
1616
import * as DesktopWindow from "../window/DesktopWindow.ts";
1717

18+
export class DesktopLifecycleRelaunchError extends Schema.TaggedErrorClass<DesktopLifecycleRelaunchError>()(
19+
"DesktopLifecycleRelaunchError",
20+
{
21+
reason: Schema.String,
22+
cause: Schema.Defect(),
23+
},
24+
) {
25+
override get message(): string {
26+
return `Desktop relaunch failed for reason "${this.reason}".`;
27+
}
28+
}
29+
1830
export type DesktopLifecycleRuntimeServices =
1931
| DesktopEnvironment.DesktopEnvironment
2032
| DesktopShutdown.DesktopShutdown
@@ -142,11 +154,10 @@ export const make = DesktopLifecycle.of({
142154
});
143155
yield* electronApp.exit(0);
144156
}).pipe(
145-
Effect.catchCause((cause) =>
146-
logLifecycleError("desktop relaunch failed", {
147-
cause: Cause.pretty(cause),
148-
}),
149-
),
157+
Effect.catchCause((cause) => {
158+
const error = new DesktopLifecycleRelaunchError({ reason, cause });
159+
return logLifecycleError(error.message, { error });
160+
}),
150161
Effect.forkDetach,
151162
Effect.asVoid,
152163
);

apps/desktop/src/window/DesktopApplicationMenu.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import * as Cause from "effect/Cause";
21
import * as Context from "effect/Context";
32
import * as Effect from "effect/Effect";
43
import * as Layer from "effect/Layer";
54
import * as Option from "effect/Option";
5+
import * as Schema from "effect/Schema";
66

77
import type * as Electron from "electron";
88

@@ -14,6 +14,18 @@ import * as DesktopEnvironment from "../app/DesktopEnvironment.ts";
1414
import * as DesktopUpdates from "../updates/DesktopUpdates.ts";
1515
import * as DesktopWindow from "./DesktopWindow.ts";
1616

17+
export class DesktopApplicationMenuActionError extends Schema.TaggedErrorClass<DesktopApplicationMenuActionError>()(
18+
"DesktopApplicationMenuActionError",
19+
{
20+
action: Schema.String,
21+
cause: Schema.Defect(),
22+
},
23+
) {
24+
override get message(): string {
25+
return `Desktop menu action "${this.action}" failed.`;
26+
}
27+
}
28+
1729
export class DesktopApplicationMenu extends Context.Service<
1830
DesktopApplicationMenu,
1931
{
@@ -100,12 +112,10 @@ export const make = Effect.gen(function* () {
100112
effect.pipe(
101113
Effect.annotateLogs({ action }),
102114
Effect.withSpan("desktop.menu.action"),
103-
Effect.catchCause((cause) =>
104-
logMenuError("desktop menu action failed", {
105-
action,
106-
cause: Cause.pretty(cause),
107-
}),
108-
),
115+
Effect.catchCause((cause) => {
116+
const error = new DesktopApplicationMenuActionError({ action, cause });
117+
return logMenuError(error.message, { error });
118+
}),
109119
),
110120
);
111121
};

0 commit comments

Comments
 (0)