Skip to content

Commit 02cac6d

Browse files
committed
fix: use Effect.flatMap for decodeJjCurrentChange to route errors to typed channel
decodeJjCurrentChange was throwing VcsOutputDecodeError inside Effect.map, which causes the error to become an unrecoverable defect rather than a typed error in the VcsError channel. Changed the function to return an Effect and use Effect.flatMap at the call site so errors properly land in the typed error channel as the type signature promises.
1 parent e2e40c2 commit 02cac6d

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

‎apps/server/src/vcs/JjVcsDriver.ts‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,27 +80,32 @@ function parseNullRecord(record: string): string[] {
8080
return record.split("\0").map((value) => value.trim());
8181
}
8282

83-
function decodeJjCurrentChange(raw: string, cwd: string): JjCurrentChange | null {
83+
function decodeJjCurrentChange(
84+
raw: string,
85+
cwd: string,
86+
): Effect.Effect<JjCurrentChange | null, VcsOutputDecodeError> {
8487
const trimmed = raw.trim();
8588
if (trimmed.length === 0) {
86-
return null;
89+
return Effect.succeed(null);
8790
}
8891

8992
const [changeId, commitId, description] = parseNullRecord(trimmed);
9093
if (!changeId) {
91-
throw new VcsOutputDecodeError({
92-
operation: "JjVcsDriver.currentChange",
93-
command: "jj log",
94-
cwd,
95-
detail: "jj current change output did not include a change id",
96-
});
94+
return Effect.fail(
95+
new VcsOutputDecodeError({
96+
operation: "JjVcsDriver.currentChange",
97+
command: "jj log",
98+
cwd,
99+
detail: "jj current change output did not include a change id",
100+
}),
101+
);
97102
}
98103

99-
return {
104+
return Effect.succeed({
100105
changeId,
101106
commitId: commitId || null,
102107
description: description || null,
103-
};
108+
});
104109
}
105110

106111
function decodeJjBookmarkList(raw: string): ReadonlyArray<JjBookmark> {
@@ -370,7 +375,7 @@ export const makeVcsDriverShape = Effect.fn("makeJjVcsDriverShape")(function* ()
370375
timeoutMs: 5_000,
371376
maxOutputBytes: 64 * 1024,
372377
},
373-
).pipe(Effect.map((result) => decodeJjCurrentChange(result.stdout, cwd)));
378+
).pipe(Effect.flatMap((result) => decodeJjCurrentChange(result.stdout, cwd)));
374379

375380
const listBookmarks: JjVcsDriverShape["listBookmarks"] = (cwd) =>
376381
jjCommand(

0 commit comments

Comments
 (0)