Explorar o código

fix(db-sync): normalize tx-reject payload shapes

Tienson Qin hai 3 días
pai
achega
75bf1e683b

+ 1 - 0
deps/db-sync/src/logseq/db_sync/malli_schema.cljs

@@ -52,6 +52,7 @@
    [:t {:optional true} :int]
    [:t {:optional true} :int]
    [:success-tx-ids {:optional true} [:sequential :uuid]]
    [:success-tx-ids {:optional true} [:sequential :uuid]]
    [:failed-tx-id {:optional true} :uuid]
    [:failed-tx-id {:optional true} :uuid]
+   [:error-detail {:optional true} :string]
    [:data {:optional true} :string]])
    [:data {:optional true} :string]])
 
 
 (def user-presence-schema
 (def user-presence-schema

+ 10 - 2
deps/db-sync/src/logseq/db_sync/protocol.cljs

@@ -1,5 +1,12 @@
 (ns logseq.db-sync.protocol
 (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]
 (defn parse-message [raw]
   (try
   (try
@@ -10,7 +17,8 @@
       nil)))
       nil)))
 
 
 (defn encode-message [m]
 (defn encode-message [m]
-  (js/JSON.stringify (clj->js m)))
+  (js/JSON.stringify
+   (clj->js (walk/postwalk stringify-uuid m))))
 
 
 (defn transit->tx [value]
 (defn transit->tx [value]
   (common/read-transit value))
   (common/read-transit value))

+ 16 - 0
deps/db-sync/test/logseq/db_sync/worker_handler_ws_test.cljs

@@ -66,6 +66,22 @@
     (is (= "hello" (:type @sent)))
     (is (= "hello" (:type @sent)))
     (is (false? (contains? @sent :checksum)))))
     (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
 (deftest websocket-connection-is-rejected-while-snapshot-upload-is-in-progress-test
   (async done
   (async done
          (let [accepted (atom [])
          (let [accepted (atom [])

+ 17 - 3
src/main/frontend/worker/sync/transport.cljs

@@ -53,9 +53,23 @@
 (defn coerce-ws-server-message
 (defn coerce-ws-server-message
   [message]
   [message]
   (when 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
 (defn parse-transit
   [fail-fast-f value context]
   [fail-fast-f value context]