From 2bafed5b8594268ddb7ee86a8c38078e9af80f8e Mon Sep 17 00:00:00 2001 From: lyon Date: Sun, 21 Jun 2026 21:38:30 +0800 Subject: [PATCH] fix workbench runtime nullable json reads --- internal/cloud/server-workbench-http.ts | 9 +++++++++ internal/workbenchruntime/service.go | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/internal/cloud/server-workbench-http.ts b/internal/cloud/server-workbench-http.ts index 47eace1f..525b0f2a 100644 --- a/internal/cloud/server-workbench-http.ts +++ b/internal/cloud/server-workbench-http.ts @@ -1890,6 +1890,15 @@ function handleWorkbenchReadModelFailure(response, url, options = {}, error) { function classifyWorkbenchReadModelFailure(error) { const message = String(error?.message ?? error ?? ""); const code = String(error?.code ?? "").toLowerCase(); + const runtimeStatus = Number(error?.data?.status ?? 0); + const runtimePayloadError = error?.data?.payload?.error ?? null; + if (error?.name === "WorkbenchRuntimeDependencyError" || code.startsWith("workbench_runtime_")) { + return { + statusCode: Number.isFinite(runtimeStatus) && runtimeStatus >= 500 ? 503 : 500, + code: String(runtimePayloadError?.code ?? error?.code ?? "workbench_runtime_dependency_failed"), + message: String(runtimePayloadError?.message ?? error?.message ?? "Workbench runtime dependency failed.") + }; + } if (/timeout|connection terminated|terminating connection|econnreset|econnrefused|etimedout/iu.test(message) || /timeout|econnreset|econnrefused|etimedout/u.test(code)) { return { statusCode: 503, diff --git a/internal/workbenchruntime/service.go b/internal/workbenchruntime/service.go index fd55a3af..1c809248 100644 --- a/internal/workbenchruntime/service.go +++ b/internal/workbenchruntime/service.go @@ -480,12 +480,12 @@ func (s *Server) queryJSONColumn(ctx context.Context, sqlText string, args []any defer rows.Close() result := []any{} for rows.Next() { - var raw []byte + var raw sql.NullString if err := rows.Scan(&raw); err != nil { return nil, err } var item any - if len(raw) > 0 && json.Unmarshal(raw, &item) == nil && item != nil { + if raw.Valid && strings.TrimSpace(raw.String) != "" && json.Unmarshal([]byte(raw.String), &item) == nil && item != nil { result = append(result, item) } } @@ -571,14 +571,14 @@ func (s *Server) readProjectionOutbox(ctx context.Context, query outboxQuery) ([ var outboxSeq, projectedSeq, sourceSeq sql.NullInt64 var traceID, sessionID, turnID, messageID, sourceEventID, commitType sql.NullString var terminal, sealed sql.NullBool - var raw []byte + var raw sql.NullString var createdAt sql.NullTime if err := rows.Scan(&outboxSeq, &traceID, &sessionID, &turnID, &messageID, &projectedSeq, &sourceSeq, &sourceEventID, &commitType, &terminal, &sealed, &raw, &createdAt); err != nil { return nil, err } var payload any - if len(raw) > 0 { - _ = json.Unmarshal(raw, &payload) + if raw.Valid && strings.TrimSpace(raw.String) != "" { + _ = json.Unmarshal([]byte(raw.String), &payload) } result = append(result, map[string]any{ "outboxSeq": nullableInt(outboxSeq),