From d54484dff274f9c930e9628eeb3f6906d647127a Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Thu, 23 Apr 2026 19:50:07 +0800 Subject: [PATCH] fix(test): silence expected errors and task fail arity --- src/main/frontend/common/crypt.cljs | 11 ++++- src/main/frontend/common/missionary.cljs | 18 ++++--- src/main/frontend/handler/worker.cljs | 12 ++++- src/main/frontend/worker/undo_redo.cljs | 17 +++++-- src/test/frontend/handler/worker_test.cljs | 44 +++++++++++------ src/test/frontend/test/noise.cljs | 31 ++++++++++++ .../frontend/worker/db_sync_sim_test.cljs | 5 +- src/test/frontend/worker/db_sync_test.cljs | 49 ++++++++++++++----- 8 files changed, 143 insertions(+), 44 deletions(-) create mode 100644 src/test/frontend/test/noise.cljs diff --git a/src/main/frontend/common/crypt.cljs b/src/main/frontend/common/crypt.cljs index a3f4c78a43..1e52235d77 100644 --- a/src/main/frontend/common/crypt.cljs +++ b/src/main/frontend/common/crypt.cljs @@ -6,6 +6,11 @@ (defonce subtle (.. js/crypto -subtle)) +(defn- expected-crypto-operation-error? + [e] + (= "OperationError" (or (some-> e .-name) + (some-> e ex-cause .-name)))) + (defn data bean/->clj (get-in [:value :value]))] - (js/console.error "Unexpected webworker error:" error-value) - (js/console.log (:stack error-value)) + (when-not (suppress-worker-error-log? error-value) + (js/console.error "Unexpected webworker error:" error-value) + (when-let [stack (:stack error-value)] + (js/console.log stack))) (report-worker-error! error-value)) (js/console.error "Unexpected webworker error :" data)) (if (string? data) diff --git a/src/main/frontend/worker/undo_redo.cljs b/src/main/frontend/worker/undo_redo.cljs index fd103812a6..8d84bc88a8 100644 --- a/src/main/frontend/worker/undo_redo.cljs +++ b/src/main/frontend/worker/undo_redo.cljs @@ -166,6 +166,12 @@ (contains? #{:invalid-history-action-ops} reason))) +(defn- expected-invalid-history-action-reason? + [reason] + (contains? #{:invalid-history-action-ops + :invalid-history-action-tx} + reason)) + (declare undo-redo-aux) (defn- empty-stack-result @@ -226,11 +232,12 @@ :else (do - (log/error ::undo-redo-worker-action-unavailable - {:undo? undo? - :repo repo - :tx-id tx-id - :result worker-result}) + (when-not (expected-invalid-history-action-reason? (:reason worker-result)) + (log/error ::undo-redo-worker-action-unavailable + {:undo? undo? + :repo repo + :tx-id tx-id + :result worker-result})) (clear-history! repo) (empty-stack-result undo?)))) (catch :default e diff --git a/src/test/frontend/handler/worker_test.cljs b/src/test/frontend/handler/worker_test.cljs index d0040c0d1c..179ad5c070 100644 --- a/src/test/frontend/handler/worker_test.cljs +++ b/src/test/frontend/handler/worker_test.cljs @@ -5,6 +5,8 @@ (deftest handle-message-reports-comlink-worker-throw-with-extra-data-test (let [captured-events (atom []) + logged-errors (atom []) + logged-stacks (atom []) worker (js-obj) worker-error {:message "Non-transact outliner ops contain numeric entity ids" :data {:stage :forward-outliner-ops @@ -14,19 +16,29 @@ event #js {:data #js {:type "HANDLER" :name "throw" :value #js {:isError true - :value (clj->js worker-error)}}}] - (with-redefs [state/pub-event! (fn [payload] - (swap! captured-events conj payload))] - (worker-handler/handle-message! worker nil) - ((.-onmessage worker) event) - (is (= 1 (count @captured-events))) - (let [[event-type payload] (first @captured-events)] - (is (= :capture-error event-type)) - (is (= true (get-in payload [:payload :worker-error?]))) - (is (= {:stage "forward-outliner-ops" - :index 0} - (get-in payload [:extra :worker-error-data]))) - (is (= {:op "save-block"} - (get-in payload [:extra :worker-cause-data]))) - (is (= (:message worker-error) - (ex-message (:error payload)))))))) + :value (clj->js worker-error)}}} + orig-console-error (.-error js/console) + orig-console-log (.-log js/console)] + (aset js/console "error" (fn [& args] (swap! logged-errors conj args))) + (aset js/console "log" (fn [& args] (swap! logged-stacks conj args))) + (try + (with-redefs [state/pub-event! (fn [payload] + (swap! captured-events conj payload))] + (worker-handler/handle-message! worker nil) + ((.-onmessage worker) event) + (is (= 1 (count @captured-events))) + (let [[event-type payload] (first @captured-events)] + (is (= :capture-error event-type)) + (is (= true (get-in payload [:payload :worker-error?]))) + (is (= {:stage "forward-outliner-ops" + :index 0} + (get-in payload [:extra :worker-error-data]))) + (is (= {:op "save-block"} + (get-in payload [:extra :worker-cause-data]))) + (is (= (:message worker-error) + (ex-message (:error payload)))) + (is (empty? @logged-errors)) + (is (empty? @logged-stacks)))) + (finally + (aset js/console "error" orig-console-error) + (aset js/console "log" orig-console-log))))) diff --git a/src/test/frontend/test/noise.cljs b/src/test/frontend/test/noise.cljs new file mode 100644 index 0000000000..72a0423330 --- /dev/null +++ b/src/test/frontend/test/noise.cljs @@ -0,0 +1,31 @@ +(ns frontend.test.noise + "Shared helpers for muting noisy console output in passing test namespaces.") + +(def ^:private default-console-methods + ["error" "warn" "log" "info" "debug"]) + +(defonce ^:private *console-state + (atom {})) + +(defn- mute-console! + [key methods*] + (let [originals (zipmap methods* (map #(aget js/console %) methods*))] + (swap! *console-state assoc key originals) + (doseq [method methods*] + (aset js/console method (fn [& _] nil))))) + +(defn- restore-console! + [key methods*] + (when-let [originals (get @*console-state key)] + (doseq [method methods*] + (when-let [original (get originals method)] + (aset js/console method original))) + (swap! *console-state dissoc key))) + +(defn mute-console-fixture + "Returns a cljs.test fixture map that mutes console output during the namespace run." + ([key] + (mute-console-fixture key default-console-methods)) + ([key methods*] + {:before #(mute-console! key methods*) + :after #(restore-console! key methods*)})) diff --git a/src/test/frontend/worker/db_sync_sim_test.cljs b/src/test/frontend/worker/db_sync_sim_test.cljs index 862d649d9e..7c85dbbe63 100644 --- a/src/test/frontend/worker/db_sync_sim_test.cljs +++ b/src/test/frontend/worker/db_sync_sim_test.cljs @@ -1,11 +1,12 @@ (ns frontend.worker.db-sync-sim-test - (:require [cljs.test :refer [deftest is testing]] + (:require [cljs.test :refer [deftest is testing use-fixtures]] [clojure.data :as data] [clojure.set :as set] [clojure.string :as string] [datascript.core :as d] [frontend.db.conn-state :as db-conn-state] [frontend.state :as state] + [frontend.test.noise :as test-noise] [frontend.worker.handler.page :as worker-page] [frontend.worker.state :as worker-state] [frontend.worker.sync :as db-sync] @@ -26,6 +27,8 @@ (def ^:private base-page-title "Home") (def ^:private default-seed 1337) +(use-fixtures :once (test-noise/mute-console-fixture ::db-sync-sim-test)) + (defn- new-client-ops-db [] (let [Database (js/require "better-sqlite3") diff --git a/src/test/frontend/worker/db_sync_test.cljs b/src/test/frontend/worker/db_sync_test.cljs index 2e0b24b161..bec77f424e 100644 --- a/src/test/frontend/worker/db_sync_test.cljs +++ b/src/test/frontend/worker/db_sync_test.cljs @@ -1,6 +1,6 @@ (ns frontend.worker.db-sync-test (:require - [cljs.test :refer [async deftest is testing]] + [cljs.test :refer [async deftest is testing use-fixtures]] [clojure.set :as set] [clojure.string :as string] [datascript.core :as d] @@ -22,6 +22,7 @@ [frontend.worker.sync.temp-sqlite :as sync-temp-sqlite] [frontend.worker.sync.transport :as sync-transport] [frontend.worker.sync.upload :as sync-upload] + [frontend.test.noise :as test-noise] [frontend.worker.undo-redo :as undo-redo] [logseq.common.config :as common-config] [logseq.common.util :as common-util] @@ -52,6 +53,18 @@ :logseq.property.recycle/original-page :logseq.property.recycle/original-order}) +(defn- with-silenced-console-error + "Silences expected error logging without swallowing thrown exceptions." + [f] + (let [original-console-error (.-error js/console)] + (aset js/console "error" (fn [& _] nil)) + (try + (f) + (finally + (aset js/console "error" original-console-error))))) + +(use-fixtures :once (test-noise/mute-console-fixture ::db-sync-test)) + (defn- js-row [m] (let [row (js-obj)] @@ -724,7 +737,8 @@ (reset! *captured {:type type :payload payload}))] (try - (sync-handle-message/handle-message! test-repo client raw-message) + (with-silenced-console-error + #(sync-handle-message/handle-message! test-repo client raw-message)) (is false "expected tx/reject to fail-fast with rejected tx details") (catch :default error (let [data (ex-data error) @@ -763,12 +777,17 @@ :db-sync/pending? true}]) (with-redefs [client-op/get-local-tx (constantly 0)] (let [error (try - (sync-handle-message/handle-message! test-repo client raw-message) + (with-silenced-console-error + #(sync-handle-message/handle-message! test-repo client raw-message)) nil (catch :default e e)) ent (client-op-tx-row client-ops-conn tx-id)] (is (some? error)) + (is (= :db-sync/tx-rejected + (:type (ex-data error)))) + (is (= "db transact failed" + (:reason (ex-data error)))) (is (= [] @(:inflight client))) (is (= 0 (aget ent "pending"))) (is (= 1 (aget ent "failed")))))))))) @@ -805,7 +824,8 @@ :db-sync/pending? true}]) (with-redefs [client-op/get-local-tx (constantly 0)] (let [error (try - (sync-handle-message/handle-message! test-repo client raw-message) + (with-silenced-console-error + #(sync-handle-message/handle-message! test-repo client raw-message)) nil (catch :default e e)) @@ -813,6 +833,10 @@ failed-ent (client-op-tx-row client-ops-conn failed-tx-id) untouched-ent (client-op-tx-row client-ops-conn untouched-tx-id)] (is (some? error)) + (is (= :db-sync/tx-rejected + (:type (ex-data error)))) + (is (= "db transact failed" + (:reason (ex-data error)))) (is (= [] @(:inflight client))) (is (= 0 (aget success-ent "pending"))) (is (not= 1 (aget success-ent "failed"))) @@ -2373,14 +2397,15 @@ page-uuid (:block/uuid (:block/page seed)) block-uuid (random-uuid)] (is (thrown? js/Error - (#'sync-apply/replay-canonical-outliner-op! - conn - [:save-block [{:block/uuid block-uuid - :block/title "" - :block/parent [:block/uuid page-uuid] - :block/page [:block/uuid page-uuid] - :block/order "a0"} - nil]]))) + (with-silenced-console-error + #(#'sync-apply/replay-canonical-outliner-op! + conn + [:save-block [{:block/uuid block-uuid + :block/title "" + :block/parent [:block/uuid page-uuid] + :block/page [:block/uuid page-uuid] + :block/order "a0"} + nil]])))) (is (nil? (d/entity @conn [:block/uuid block-uuid])))))) (deftest apply-history-action-redo-replays-status-property-test