diff --git a/src/main/frontend/worker/db/fix.cljs b/src/main/frontend/worker/db/fix.cljs index 2bbabd3c8..484057a8b 100644 --- a/src/main/frontend/worker/db/fix.cljs +++ b/src/main/frontend/worker/db/fix.cljs @@ -9,14 +9,21 @@ [frontend.worker.util :as worker-util])) (defn- fix-parent-broken-chain - [db parent-id] + [db parent-id tx-report] (let [parent (d/entity db parent-id) parent-id (:db/id parent) blocks (:block/_parent parent)] (when (seq blocks) (let [children-ids (set (map :db/id blocks)) sorted (ldb/sort-by-left blocks parent) - broken-chain? (not= (count sorted) (count blocks))] + valid-left-ids (set (cons (:db/id parent) (map :db/id blocks))) + broken-chain? (or (not= (count sorted) (count blocks)) + ;; :block/left points to other blocks that're not current parent or its children + (not (every? (fn [b] (contains? valid-left-ids (:db/id (:block/left b)))) blocks)))] + (when (and (exists? js/process) broken-chain?) + (throw (ex-info "outliner broken chain" {:tx-meta (:tx-meta tx-report) + :tx-data (:tx-data tx-report) + :db-before (:db-before tx-report)}))) (when broken-chain? (let [error-data {:parent {:db/id parent-id :block/uuid (:block/uuid parent) @@ -92,9 +99,9 @@ (apply concat)))))))) (defn- fix-broken-chain - [db parent-left->es] + [db parent-left->es tx-report] (let [parents (distinct (map first (keys parent-left->es)))] - (mapcat #(fix-parent-broken-chain db %) parents))) + (mapcat #(fix-parent-broken-chain db % tx-report) parents))) (defn- build-parent-left->es [db page-id] @@ -142,6 +149,8 @@ [conn page-id transact-opts *fix-tx-data] (let [db @conn conflicts (get-conflicts db page-id) + _ (when (and (exists? js/process) (seq conflicts)) + (throw (ex-info "outliner core conflicts" {:conflicts conflicts}))) fix-conflicts-tx (when (seq conflicts) (fix-parent-left-conflicts db conflicts page-id))] (when (seq fix-conflicts-tx) @@ -154,7 +163,7 @@ (defn fix-page-if-broken! "Fix the page if it has either parent-left conflicts or broken chains." - [conn page-id {:keys [fix-parent-left? fix-broken-chain? replace-tx?] + [conn page-id {:keys [fix-parent-left? fix-broken-chain? replace-tx? tx-report] :or {fix-parent-left? true fix-broken-chain? true replace-tx? false} @@ -170,7 +179,7 @@ (when fix-broken-chain? (let [db' @conn parent-left->es' (build-parent-left->es db page-id) - fix-broken-chain-tx (fix-broken-chain db' parent-left->es')] + fix-broken-chain-tx (fix-broken-chain db' parent-left->es' tx-report)] (when (seq fix-broken-chain-tx) (let [tx-data (:tx-data (ldb/transact! conn fix-broken-chain-tx transact-opts))] (swap! *fix-tx-data (fn [old-data] (concat old-data tx-data))))))) diff --git a/src/main/frontend/worker/pipeline.cljs b/src/main/frontend/worker/pipeline.cljs index 78c7d8579..e0f478b00 100644 --- a/src/main/frontend/worker/pipeline.cljs +++ b/src/main/frontend/worker/pipeline.cljs @@ -49,7 +49,7 @@ (remove nil?))))) (defn fix-db! - [conn {:keys [db-before db-after tx-data]}] + [conn {:keys [db-before db-after tx-data] :as tx-report}] (let [changed-pages (->> (filter (fn [d] (contains? #{:block/left :block/parent} (:a d))) tx-data) (map :e) distinct @@ -61,7 +61,7 @@ (remove nil?) (distinct))] (doseq [changed-page-id changed-pages] - (db-fix/fix-page-if-broken! conn changed-page-id {})))) + (db-fix/fix-page-if-broken! conn changed-page-id {:tx-report tx-report})))) (defn validate-and-fix-db! [repo conn tx-report context] @@ -70,8 +70,8 @@ (when (and (get-in context [:validate-db-options :fail-invalid?]) (not valid?)) (worker-util/post-message :notification [["Invalid DB!"] :error])))) - (when (and (:dev? context) - (not (:node-test? context))) + (when (or (:dev? context) + (exists? js/process)) (fix-db! conn tx-report))) (defn invoke-hooks diff --git a/src/test/frontend/worker/fixtures.cljs b/src/test/frontend/worker/fixtures.cljs index 3be8f5124..69f152446 100644 --- a/src/test/frontend/worker/fixtures.cljs +++ b/src/test/frontend/worker/fixtures.cljs @@ -12,7 +12,7 @@ (assert (some? test-db-conn)) (worker-undo-redo/clear-undo-redo-stack) (worker-db-listener/listen-db-changes! test-helper/test-db-name-db-version test-db-conn - {:handler-keys [:gen-undo-ops]}) + {:handler-keys [:gen-undo-ops :sync-db-to-main-thread]}) (f) (d/unlisten! test-db-conn :frontend.worker.db-listener/listen-db-changes!))) diff --git a/src/test/frontend/worker/undo_redo_test.cljs b/src/test/frontend/worker/undo_redo_test.cljs index b6ffd1bf6..a7ee942ae 100644 --- a/src/test/frontend/worker/undo_redo_test.cljs +++ b/src/test/frontend/worker/undo_redo_test.cljs @@ -275,7 +275,7 @@ (catch :default e (let [data (ex-data e)] (fs-node/writeFileSync "debug.json" (sqlite-util/write-transit-str data)) - (throw (ex-info "stop now" {})))))) + (throw e)))))