authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 20:20:04-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 20:20:04-07:00
log6155f5cf64e9f26d10f3c912985f8ca09f9c3fef
treedee5559c0b4f63e0a2fd1186cf8dc23cf5528f72
parente3970e755b0da65c3fd83a985cede1840164ae0b
signature Signed by PGP key B5690EEEBB952194

[codex] Preserve VCS project config error causes (#3474)

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

2 files changed, 28 insertions(+), 22 deletions(-)

apps/server/src/vcs/VcsProjectConfig.test.ts+20-15
......@@ -96,16 +96,19 @@ describe("VcsProjectConfig", () => {
9696 const kind = yield* config.resolveKind({ cwd });
9797
9898 assert.equal(kind, "jj");
99 const [message, context] = messages[0] as [string, Record<string, unknown>];
10099 const failedCandidate = path.join(cwd, ".t3code", "vcs.json");
101 assert.equal(message, "Failed to inspect VCS project config at " + failedCandidate + ".");
102 assert.deepInclude(context, {
100 const [error] = messages[0] as ReadonlyArray<unknown>;
101 assert.instanceOf(error, VcsProjectConfig.VcsProjectConfigError);
102 assert.equal(
103 error.message,
104 "Failed to inspect VCS project config at " + failedCandidate + ".",
105 );
106 assert.deepInclude(error, {
103107 operation: "inspect",
104108 cwd,
105109 configPath: failedCandidate,
106 errorTag: "VcsProjectConfigError",
110 _tag: "VcsProjectConfigError",
107111 });
108 assert.equal("cause" in context, false);
109112 }).pipe(Effect.provide(Logger.layer([logger], { mergeWithExisting: false })));
110113 });
111114 });
......@@ -146,18 +149,19 @@ describe("VcsProjectConfig", () => {
146149 const kind = yield* config.resolveKind({ cwd: root });
147150
148151 assert.equal(kind, "auto");
149 const [message, context] = messages[0] as [string, Record<string, unknown>];
152 const [error] = messages[0] as ReadonlyArray<unknown>;
153 assert.instanceOf(error, VcsProjectConfig.VcsProjectConfigError);
150154 assert.equal(
151 message,
155 error.message,
152156 "Failed to decode VCS project config at " + path.join(configDir, "vcs.json") + ".",
153157 );
154 assert.deepInclude(context, {
158 assert.deepInclude(error.cause, { _tag: "SchemaError" });
159 assert.deepInclude(error, {
155160 operation: "decode",
156161 cwd: root,
157162 configPath: path.join(configDir, "vcs.json"),
158 errorTag: "VcsProjectConfigError",
163 _tag: "VcsProjectConfigError",
159164 });
160 assert.equal("cause" in context, false);
161165 }).pipe(Effect.provide(Logger.layer([logger], { mergeWithExisting: false })));
162166 });
163167 });
......@@ -182,15 +186,16 @@ describe("VcsProjectConfig", () => {
182186 const kind = yield* config.resolveKind({ cwd: root });
183187
184188 assert.equal(kind, "auto");
185 const [message, context] = messages[0] as [string, Record<string, unknown>];
186 assert.equal(message, "Failed to read VCS project config at " + configPath + ".");
187 assert.deepInclude(context, {
189 const [error] = messages[0] as ReadonlyArray<unknown>;
190 assert.instanceOf(error, VcsProjectConfig.VcsProjectConfigError);
191 assert.equal(error.message, "Failed to read VCS project config at " + configPath + ".");
192 assert.deepInclude(error.cause, { _tag: "PlatformError" });
193 assert.deepInclude(error, {
188194 operation: "read",
189195 cwd: root,
190196 configPath,
191 errorTag: "VcsProjectConfigError",
197 _tag: "VcsProjectConfigError",
192198 });
193 assert.equal("cause" in context, false);
194199 }).pipe(Effect.provide(Logger.layer([logger], { mergeWithExisting: false })));
195200 });
196201 });
apps/server/src/vcs/VcsProjectConfig.ts+8-7
......@@ -55,13 +55,14 @@ function configuredKind(config: ProjectVcsConfigFile): VcsDriverKindType | "auto
5555}
5656
5757const logVcsProjectConfigError = (error: VcsProjectConfigError) =>
58 Effect.logWarning(error.message, {
59 operation: error.operation,
60 cwd: error.cwd,
61 configPath: error.configPath,
62 errorTag: error._tag,
63 stack: error.stack,
64 });
58 Effect.logWarning(error).pipe(
59 Effect.annotateLogs({
60 operation: error.operation,
61 cwd: error.cwd,
62 configPath: error.configPath,
63 errorTag: error._tag,
64 }),
65 );
6566
6667export const make = Effect.gen(function* () {
6768 const fileSystem = yield* FileSystem.FileSystem;