authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-10 10:38:11-07:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-10 10:38:11-07:00
log13eeb07f5f4b582e2ff824db382ff8917489c5c6
tree8978958fc97729744578a5ba50c9889d194a99ed
parent1e9bac7f6e783fe0498ddeb8392c5f4b50aad19d

prevent squashing some know errors


4 files changed, 22 insertions(+), 43 deletions(-)

apps/server/src/orchestration/Layers/OrchestrationEngine.ts+1-8
...@@ -49,13 +49,6 @@ function commandToAggregateRef(command: OrchestrationCommand): {...@@ -49,13 +49,6 @@ function commandToAggregateRef(command: OrchestrationCommand): {
49 }49 }
50}50}
5151
52function formatDispatchError(error: OrchestrationDispatchError): string {
53 if (error instanceof Error && error.message.length > 0) {
54 return error.message;
55 }
56 return String(error);
57}
58
59const makeOrchestrationEngine = Effect.gen(function* () {52const makeOrchestrationEngine = Effect.gen(function* () {
60 const sql = yield* SqlClient.SqlClient;53 const sql = yield* SqlClient.SqlClient;
61 const eventStore = yield* OrchestrationEventStore;54 const eventStore = yield* OrchestrationEventStore;
...@@ -191,7 +184,7 @@ const makeOrchestrationEngine = Effect.gen(function* () {...@@ -191,7 +184,7 @@ const makeOrchestrationEngine = Effect.gen(function* () {
191 acceptedAt: new Date().toISOString(),184 acceptedAt: new Date().toISOString(),
192 resultSequence: readModel.snapshotSequence,185 resultSequence: readModel.snapshotSequence,
193 status: "rejected",186 status: "rejected",
194 error: formatDispatchError(error),187 error: error.message,
195 })188 })
196 .pipe(Effect.catch(() => Effect.void));189 .pipe(Effect.catch(() => Effect.void));
197 }190 }
apps/server/src/orchestration/Layers/ProviderCommandReactor.ts+7-20
...@@ -16,7 +16,7 @@ import { Cache, Cause, Duration, Effect, Layer, Option, Queue, Schema, Stream }...@@ -16,7 +16,7 @@ import { Cache, Cause, Duration, Effect, Layer, Option, Queue, Schema, Stream }
1616
17import { resolveThreadWorkspaceCwd } from "../../checkpointing/Utils.ts";17import { resolveThreadWorkspaceCwd } from "../../checkpointing/Utils.ts";
18import { GitCore } from "../../git/Services/GitCore.ts";18import { GitCore } from "../../git/Services/GitCore.ts";
19import { ProviderAdapterRequestError } from "../../provider/Errors.ts";19import { ProviderAdapterRequestError, ProviderServiceError } from "../../provider/Errors.ts";
20import { TextGeneration } from "../../git/Services/TextGeneration.ts";20import { TextGeneration } from "../../git/Services/TextGeneration.ts";
21import { ProviderService } from "../../provider/Services/ProviderService.ts";21import { ProviderService } from "../../provider/Services/ProviderService.ts";
22import { OrchestrationEngineService } from "../Services/OrchestrationEngine.ts";22import { OrchestrationEngineService } from "../Services/OrchestrationEngine.ts";
...@@ -73,18 +73,8 @@ const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access";...@@ -73,18 +73,8 @@ const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access";
73const WORKTREE_BRANCH_PREFIX = "t3code";73const WORKTREE_BRANCH_PREFIX = "t3code";
74const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(`^${WORKTREE_BRANCH_PREFIX}\\/[0-9a-f]{8}$`);74const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(`^${WORKTREE_BRANCH_PREFIX}\\/[0-9a-f]{8}$`);
7575
76function toErrorMessage(error: unknown): string {76function isUnknownPendingApprovalRequestError(cause: Cause.Cause<ProviderServiceError>): boolean {
77 if (error instanceof Error && error.message.trim().length > 0) {77 const error = Cause.squash(cause);
78 return error.message;
79 }
80 try {
81 return JSON.stringify(error);
82 } catch {
83 return String(error);
84 }
85}
86
87function isUnknownPendingApprovalRequestError(error: unknown): boolean {
88 if (Schema.is(ProviderAdapterRequestError)(error)) {78 if (Schema.is(ProviderAdapterRequestError)(error)) {
89 const detail = error.detail.toLowerCase();79 const detail = error.detail.toLowerCase();
90 return (80 return (
...@@ -92,7 +82,7 @@ function isUnknownPendingApprovalRequestError(error: unknown): boolean {...@@ -92,7 +82,7 @@ function isUnknownPendingApprovalRequestError(error: unknown): boolean {
92 detail.includes("unknown pending permission request")82 detail.includes("unknown pending permission request")
93 );83 );
94 }84 }
95 const message = toErrorMessage(error).toLowerCase();85 const message = Cause.pretty(cause);
96 return (86 return (
97 message.includes("unknown pending approval request") ||87 message.includes("unknown pending approval request") ||
98 message.includes("unknown pending permission request")88 message.includes("unknown pending permission request")
...@@ -539,19 +529,17 @@ const make = Effect.gen(function* () {...@@ -539,19 +529,17 @@ const make = Effect.gen(function* () {
539 .pipe(529 .pipe(
540 Effect.catchCause((cause) =>530 Effect.catchCause((cause) =>
541 Effect.gen(function* () {531 Effect.gen(function* () {
542 const error = Cause.squash(cause);
543 const detail = toErrorMessage(error);
544 yield* appendProviderFailureActivity({532 yield* appendProviderFailureActivity({
545 threadId: event.payload.threadId,533 threadId: event.payload.threadId,
546 kind: "provider.approval.respond.failed",534 kind: "provider.approval.respond.failed",
547 summary: "Provider approval response failed",535 summary: "Provider approval response failed",
548 detail,536 detail: Cause.pretty(cause),
549 turnId: null,537 turnId: null,
550 createdAt: event.payload.createdAt,538 createdAt: event.payload.createdAt,
551 requestId: event.payload.requestId,539 requestId: event.payload.requestId,
552 });540 });
553541
554 if (!isUnknownPendingApprovalRequestError(error)) return;542 if (!isUnknownPendingApprovalRequestError(cause)) return;
555 }),543 }),
556 ),544 ),
557 );545 );
...@@ -586,12 +574,11 @@ const make = Effect.gen(function* () {...@@ -586,12 +574,11 @@ const make = Effect.gen(function* () {
586 .pipe(574 .pipe(
587 Effect.catchCause((cause) =>575 Effect.catchCause((cause) =>
588 Effect.gen(function* () {576 Effect.gen(function* () {
589 const error = Cause.squash(cause);
590 yield* appendProviderFailureActivity({577 yield* appendProviderFailureActivity({
591 threadId: event.payload.threadId,578 threadId: event.payload.threadId,
592 kind: "provider.user-input.respond.failed",579 kind: "provider.user-input.respond.failed",
593 summary: "Provider user input response failed",580 summary: "Provider user input response failed",
594 detail: toErrorMessage(error),581 detail: Cause.pretty(cause),
595 turnId: null,582 turnId: null,
596 createdAt: event.payload.createdAt,583 createdAt: event.payload.createdAt,
597 requestId: event.payload.requestId,584 requestId: event.payload.requestId,
apps/server/src/provider/Layers/CodexAdapter.ts+11-5
...@@ -1338,11 +1338,17 @@ const makeCodexAdapter = (options?: CodexAdapterLiveOptions) =>...@@ -1338,11 +1338,17 @@ const makeCodexAdapter = (options?: CodexAdapterLiveOptions) =>
1338 new Error(`Invalid attachment id '${attachment.id}'.`),1338 new Error(`Invalid attachment id '${attachment.id}'.`),
1339 );1339 );
1340 }1340 }
1341 const bytes = yield* fileSystem1341 const bytes = yield* fileSystem.readFile(attachmentPath).pipe(
1342 .readFile(attachmentPath)1342 Effect.mapError(
1343 .pipe(1343 (cause) =>
1344 Effect.mapError((cause) => toRequestError(input.threadId, "turn/start", cause)),1344 new ProviderAdapterRequestError({
1345 );1345 provider: PROVIDER,
1346 method: "turn/start",
1347 detail: toMessage(cause, "Failed to read attachment file."),
1348 cause,
1349 }),
1350 ),
1351 );
1346 return {1352 return {
1347 type: "image" as const,1353 type: "image" as const,
1348 url: `data:${attachment.mimeType};base64,${Buffer.from(bytes).toString("base64")}`,1354 url: `data:${attachment.mimeType};base64,${Buffer.from(bytes).toString("base64")}`,
apps/server/src/wsServer.ts+3-10
...@@ -99,8 +99,7 @@ export interface ServerShape {...@@ -99,8 +99,7 @@ export interface ServerShape {
99 */99 */
100export class Server extends ServiceMap.Service<Server, ServerShape>()("t3/wsServer/Server") {}100export class Server extends ServiceMap.Service<Server, ServerShape>()("t3/wsServer/Server") {}
101101
102const isServerNotRunningError = (error: unknown): boolean => {102const isServerNotRunningError = (error: Error): boolean => {
103 if (!(error instanceof Error)) return false;
104 const maybeCode = (error as NodeJS.ErrnoException).code;103 const maybeCode = (error as NodeJS.ErrnoException).code;
105 return (104 return (
106 maybeCode === "ERR_SERVER_NOT_RUNNING" || error.message.toLowerCase().includes("not running")105 maybeCode === "ERR_SERVER_NOT_RUNNING" || error.message.toLowerCase().includes("not running")
...@@ -196,12 +195,6 @@ function stripRequestTag<T extends { _tag: string }>(body: T) {...@@ -196,12 +195,6 @@ function stripRequestTag<T extends { _tag: string }>(body: T) {
196 return Struct.omit(body, ["_tag"]);195 return Struct.omit(body, ["_tag"]);
197}196}
198197
199function messageFromCause(cause: Cause.Cause<unknown>): string {
200 const squashed = Cause.squash(cause);
201 const message = squashed instanceof Error ? squashed.message.trim() : String(squashed).trim();
202 return message.length > 0 ? message : Cause.pretty(cause);
203}
204
205export type ServerCoreRuntimeServices =198export type ServerCoreRuntimeServices =
206 | OrchestrationEngineService199 | OrchestrationEngineService
207 | ProjectionSnapshotQuery200 | ProjectionSnapshotQuery
...@@ -943,7 +936,7 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<...@@ -943,7 +936,7 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
943 if (request._tag === "Failure") {936 if (request._tag === "Failure") {
944 const errorResponse = yield* encodeResponse({937 const errorResponse = yield* encodeResponse({
945 id: "unknown",938 id: "unknown",
946 error: { message: `Invalid request format: ${messageFromCause(request.cause)}` },939 error: { message: `Invalid request format: ${Cause.pretty(request.cause)}` },
947 });940 });
948 ws.send(errorResponse);941 ws.send(errorResponse);
949 return;942 return;
...@@ -953,7 +946,7 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<...@@ -953,7 +946,7 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
953 if (result._tag === "Failure") {946 if (result._tag === "Failure") {
954 const errorResponse = yield* encodeResponse({947 const errorResponse = yield* encodeResponse({
955 id: request.value.id,948 id: request.value.id,
956 error: { message: messageFromCause(result.cause) },949 error: { message: Cause.pretty(result.cause) },
957 });950 });
958 ws.send(errorResponse);951 ws.send(errorResponse);
959 return;952 return;