From 75bf1e683bb9be2bc2144819785fac0cb86caa5e Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Thu, 9 Apr 2026 22:43:40 +0800 Subject: [PATCH] fix(db-sync): normalize tx-reject payload shapes --- .../src/logseq/db_sync/malli_schema.cljs | 1 + deps/db-sync/src/logseq/db_sync/protocol.cljs | 12 +++++++++-- .../db_sync/worker_handler_ws_test.cljs | 16 +++++++++++++++ src/main/frontend/worker/sync/transport.cljs | 20 ++++++++++++++++--- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/deps/db-sync/src/logseq/db_sync/malli_schema.cljs b/deps/db-sync/src/logseq/db_sync/malli_schema.cljs index e5437a3308..b3ed276242 100644 --- a/deps/db-sync/src/logseq/db_sync/malli_schema.cljs +++ b/deps/db-sync/src/logseq/db_sync/malli_schema.cljs @@ -52,6 +52,7 @@ [:t {:optional true} :int] [:success-tx-ids {:optional true} [:sequential :uuid]] [:failed-tx-id {:optional true} :uuid] + [:error-detail {:optional true} :string] [:data {:optional true} :string]]) (def user-presence-schema diff --git a/deps/db-sync/src/logseq/db_sync/protocol.cljs b/deps/db-sync/src/logseq/db_sync/protocol.cljs index 7657eafa21..75bc30d82d 100644 --- a/deps/db-sync/src/logseq/db_sync/protocol.cljs +++ b/deps/db-sync/src/logseq/db_sync/protocol.cljs @@ -1,5 +1,12 @@ (ns logseq.db-sync.protocol - (:require [logseq.db-sync.common :as common])) + (:require [clojure.walk :as walk] + [logseq.db-sync.common :as common])) + +(defn- stringify-uuid + [value] + (if (uuid? value) + (str value) + value)) (defn parse-message [raw] (try @@ -10,7 +17,8 @@ nil))) (defn encode-message [m] - (js/JSON.stringify (clj->js m))) + (js/JSON.stringify + (clj->js (walk/postwalk stringify-uuid m)))) (defn transit->tx [value] (common/read-transit value)) diff --git a/deps/db-sync/test/logseq/db_sync/worker_handler_ws_test.cljs b/deps/db-sync/test/logseq/db_sync/worker_handler_ws_test.cljs index 4c1d0b49d0..28c903a5c3 100644 --- a/deps/db-sync/test/logseq/db_sync/worker_handler_ws_test.cljs +++ b/deps/db-sync/test/logseq/db_sync/worker_handler_ws_test.cljs @@ -66,6 +66,22 @@ (is (= "hello" (:type @sent))) (is (false? (contains? @sent :checksum))))) +(deftest ws-send-serializes-tx-reject-uuids-as-strings-test + (let [raw* (atom nil) + ws #js {:readyState 1 + :send (fn [raw] (reset! raw* raw))} + success-tx-id (random-uuid) + failed-tx-id (random-uuid)] + (ws/send! ws {:type "tx/reject" + :reason "db transact failed" + :t 3 + :success-tx-ids [success-tx-id] + :failed-tx-id failed-tx-id}) + (let [message (-> @raw* js/JSON.parse (js->clj :keywordize-keys true))] + (is (= "tx/reject" (:type message))) + (is (= [(str success-tx-id)] (:success-tx-ids message))) + (is (= (str failed-tx-id) (:failed-tx-id message)))))) + (deftest websocket-connection-is-rejected-while-snapshot-upload-is-in-progress-test (async done (let [accepted (atom []) diff --git a/src/main/frontend/worker/sync/transport.cljs b/src/main/frontend/worker/sync/transport.cljs index 3a0b9516eb..87158d7451 100644 --- a/src/main/frontend/worker/sync/transport.cljs +++ b/src/main/frontend/worker/sync/transport.cljs @@ -53,9 +53,23 @@ (defn coerce-ws-server-message [message] (when message - (let [coerced (coerce db-sync-schema/ws-server-message-coercer message {:schema :ws/server})] - (when-not (= coerced invalid-coerce) - coerced)))) + (letfn [(uuid-like->string [value] + (cond + (uuid? value) (str value) + (and (map? value) (string? (:uuid value))) (:uuid value) + :else value)) + (normalize-legacy-tx-reject [m] + (if (= "tx/reject" (:type m)) + (cond-> m + (contains? m :failed-tx-id) (update :failed-tx-id uuid-like->string) + (contains? m :success-tx-ids) (update :success-tx-ids + (fn [ids] + (mapv uuid-like->string (or ids []))))) + m))] + (let [message* (normalize-legacy-tx-reject message) + coerced (coerce db-sync-schema/ws-server-message-coercer message* {:schema :ws/server})] + (when-not (= coerced invalid-coerce) + coerced))))) (defn parse-transit [fail-fast-f value context]