authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 17:25:27-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 17:25:27-07:00
log4cd958445f60dcdbc5ad3997a35b1bd995e9d725
tree754f307c84293e51ed100b00e9ea21a40ddba0f6
parent9f7861aadd257313efefdc690e440d23d771f315
signature Signed by PGP key B5690EEEBB952194

[codex] Migrate desktop app errors to Schema (#3449)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 43 insertions(+), 11 deletions(-)

apps/desktop/src/app/DesktopApp.ts+13-11
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1import * as Cause from "effect/Cause";1import * as Cause from "effect/Cause";
2import * as Data from "effect/Data";
3import * as Effect from "effect/Effect";2import * as Effect from "effect/Effect";
4import * as Option from "effect/Option";3import * as Option from "effect/Option";
5import * as Ref from "effect/Ref";4import * as Ref from "effect/Ref";
5import * as Schema from "effect/Schema";
66
7import * as NetService from "@t3tools/shared/Net";7import * as NetService from "@t3tools/shared/Net";
8import * as Crypto from "effect/Crypto";8import * as Crypto from "effect/Crypto";
...@@ -33,22 +33,24 @@ const makeDesktopRunId = Crypto.Crypto.pipe(...@@ -33,22 +33,24 @@ const makeDesktopRunId = Crypto.Crypto.pipe(
33 Effect.map((value) => value.replaceAll("-", "").slice(0, 12)),33 Effect.map((value) => value.replaceAll("-", "").slice(0, 12)),
34);34);
3535
36class DesktopBackendPortUnavailableError extends Data.TaggedError(36export class DesktopBackendPortUnavailableError extends Schema.TaggedErrorClass<DesktopBackendPortUnavailableError>()(
37 "DesktopBackendPortUnavailableError",37 "DesktopBackendPortUnavailableError",
38)<{38 {
39 readonly startPort: number;39 startPort: Schema.Int,
40 readonly maxPort: number;40 maxPort: Schema.Int,
41 readonly hosts: readonly string[];41 hosts: Schema.Array(Schema.String),
42}> {42 },
43 override get message() {43) {
44 override get message(): string {
44 return `No desktop backend port is available on hosts ${this.hosts.join(", ")} between ${this.startPort} and ${this.maxPort}.`;45 return `No desktop backend port is available on hosts ${this.hosts.join(", ")} between ${this.startPort} and ${this.maxPort}.`;
45 }46 }
46}47}
4748
48class DesktopDevelopmentBackendPortRequiredError extends Data.TaggedError(49export class DesktopDevelopmentBackendPortRequiredError extends Schema.TaggedErrorClass<DesktopDevelopmentBackendPortRequiredError>()(
49 "DesktopDevelopmentBackendPortRequiredError",50 "DesktopDevelopmentBackendPortRequiredError",
50)<{}> {51 {},
51 override get message() {52) {
53 override get message(): string {
52 return "T3CODE_PORT is required in desktop development.";54 return "T3CODE_PORT is required in desktop development.";
53 }55 }
54}56}
apps/desktop/src/app/DesktopAppErrors.test.ts created+30
...@@ -0,0 +1,30 @@
1import { assert, describe, it } from "@effect/vitest";
2
3import {
4 DesktopBackendPortUnavailableError,
5 DesktopDevelopmentBackendPortRequiredError,
6} from "./DesktopApp.ts";
7
8describe("DesktopApp errors", () => {
9 it("preserves unavailable backend port context", () => {
10 const error = new DesktopBackendPortUnavailableError({
11 startPort: 3_773,
12 maxPort: 65_535,
13 hosts: ["127.0.0.1", "0.0.0.0", "::"],
14 });
15
16 assert.equal(error.startPort, 3_773);
17 assert.equal(error.maxPort, 65_535);
18 assert.deepEqual(error.hosts, ["127.0.0.1", "0.0.0.0", "::"]);
19 assert.equal(
20 error.message,
21 "No desktop backend port is available on hosts 127.0.0.1, 0.0.0.0, :: between 3773 and 65535.",
22 );
23 });
24
25 it("reports the required development port", () => {
26 const error = new DesktopDevelopmentBackendPortRequiredError();
27
28 assert.equal(error.message, "T3CODE_PORT is required in desktop development.");
29 });
30});