mirror of
https://github.com/logseq/logseq.git
synced 2026-05-16 08:52:20 +00:00
fix: handle mirror file errors
This commit is contained in:
10
deps/common/src/logseq/common/graph.cljs
vendored
10
deps/common/src/logseq/common/graph.cljs
vendored
@@ -51,6 +51,11 @@
|
||||
(filter #(.isDirectory %))
|
||||
(map #(.-name %)))))
|
||||
|
||||
(defn- path-at-or-under?
|
||||
[path dir]
|
||||
(or (= path dir)
|
||||
(string/starts-with? path (str dir "/"))))
|
||||
|
||||
(defn ignored-path?
|
||||
"Given a graph directory and path, returns truthy value on whether the path is
|
||||
ignored. Useful for contexts like reading a graph's directory and file watcher
|
||||
@@ -73,8 +78,9 @@ Rules:
|
||||
rpath (path/trim-dir-prefix dir path)]
|
||||
(when (string? path)
|
||||
(or
|
||||
(some #(string/starts-with? rpath %)
|
||||
["." "logseq/.recycle" "logseq/bak" "logseq/version-files" "mirror/markdown"])
|
||||
(string/starts-with? rpath ".")
|
||||
(some #(path-at-or-under? rpath %)
|
||||
["logseq/.recycle" "logseq/bak" "logseq/version-files" "mirror/markdown"])
|
||||
(contains? #{"logseq/graphs-txid.edn" "logseq/pages-metadata.edn"} rpath)
|
||||
(some #(string/includes? rpath (str "/" % "/"))
|
||||
["node_modules"])
|
||||
|
||||
15
deps/common/test/logseq/common/graph_test.cljs
vendored
15
deps/common/test/logseq/common/graph_test.cljs
vendored
@@ -27,11 +27,24 @@
|
||||
;; Create files that are recognized
|
||||
(fs/writeFileSync "tmp/test-graph/pages/foo.md" "")
|
||||
(fs/writeFileSync "tmp/test-graph/journals/2023_05_09.md" "")
|
||||
(fs/mkdirSync (node-path/join "tmp/test-graph" "mirror" "markdown-notes") #js {:recursive true})
|
||||
(fs/mkdirSync (node-path/join "tmp/test-graph" "mirror" "markdown2") #js {:recursive true})
|
||||
(fs/writeFileSync "tmp/test-graph/mirror/markdown-notes/foo.md" "")
|
||||
(fs/writeFileSync "tmp/test-graph/mirror/markdown2/foo.md" "")
|
||||
;; Create files that are ignored
|
||||
(fs/mkdirSync (node-path/join "tmp/test-graph" "logseq" "bak"))
|
||||
(fs/mkdirSync (node-path/join "tmp/test-graph" "mirror" "markdown" "pages") #js {:recursive true})
|
||||
(fs/writeFileSync "tmp/test-graph/logseq/bak/baz.md" "")
|
||||
(fs/writeFileSync "tmp/test-graph/logseq/.gitignore" "")
|
||||
(fs/writeFileSync "tmp/test-graph/mirror/markdown/pages/foo.md" "")
|
||||
(is (= ["tmp/test-graph/journals/2023_05_09.md" "tmp/test-graph/pages/foo.md"]
|
||||
(is (= ["tmp/test-graph/journals/2023_05_09.md"
|
||||
"tmp/test-graph/mirror/markdown-notes/foo.md"
|
||||
"tmp/test-graph/mirror/markdown2/foo.md"
|
||||
"tmp/test-graph/pages/foo.md"]
|
||||
(common-graph/get-files "tmp/test-graph"))))
|
||||
|
||||
(deftest ignored-markdown-mirror-path-honors-directory-boundary-test
|
||||
(is (common-graph/ignored-path? "tmp/test-graph" "tmp/test-graph/mirror/markdown"))
|
||||
(is (common-graph/ignored-path? "tmp/test-graph" "tmp/test-graph/mirror/markdown/pages/foo.md"))
|
||||
(is (not (common-graph/ignored-path? "tmp/test-graph" "tmp/test-graph/mirror/markdown-notes/foo.md")))
|
||||
(is (not (common-graph/ignored-path? "tmp/test-graph" "tmp/test-graph/mirror/markdown2/foo.md"))))
|
||||
|
||||
@@ -145,12 +145,25 @@
|
||||
[platform*]
|
||||
(:storage platform*))
|
||||
|
||||
(defn- not-found-error?
|
||||
[error]
|
||||
(let [data (ex-data error)
|
||||
code (or (:code data) (some-> error .-code))
|
||||
name (some-> error .-name)
|
||||
message (some-> error .-message)]
|
||||
(or (contains? #{:not-found :enoent "ENOENT" "NotFoundError"} code)
|
||||
(= "NotFoundError" name)
|
||||
(boolean (some-> message (string/starts-with? "ENOENT:"))))))
|
||||
|
||||
(defn- <read-text
|
||||
[platform* path]
|
||||
(if-let [f (or (:mirror-read-text! (storage platform*))
|
||||
(:read-text! (storage platform*)))]
|
||||
(-> (f path)
|
||||
(p/catch (constantly nil)))
|
||||
(p/catch (fn [error]
|
||||
(if (not-found-error? error)
|
||||
nil
|
||||
(p/rejected error)))))
|
||||
(p/rejected (ex-info "platform storage/read-text! missing" {:path path}))))
|
||||
|
||||
(defn- <write-text-atomic!
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
(defn- page-path [path]
|
||||
(str (markdown-mirror/repo-mirror-dir test-repo) "/" path))
|
||||
|
||||
(defn- js-error
|
||||
[message data]
|
||||
(let [error (js/Error. message)]
|
||||
(doseq [[k v] data]
|
||||
(aset error (name k) v))
|
||||
error))
|
||||
|
||||
(defn- first-block [page]
|
||||
(-> page :block/_page first))
|
||||
|
||||
@@ -149,6 +156,44 @@
|
||||
(p/catch (fn [e] (is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest missing-mirror-file-read-still-writes-page-mirror-test
|
||||
(async done
|
||||
(let [{:keys [platform files writes]} (fake-platform)
|
||||
missing-error (js-error "ENOENT: missing mirror file" {:code "ENOENT"})
|
||||
conn (db-test/create-conn-with-blocks
|
||||
{:pages-and-blocks [{:page {:block/title "Page A"}
|
||||
:blocks [{:block/title "hello"}]}]})
|
||||
page (db-test/find-page-by-title @conn "Page A")]
|
||||
(-> (markdown-mirror/<mirror-page!
|
||||
test-repo @conn (:db/id page)
|
||||
{:platform (assoc-in platform [:storage :read-text!]
|
||||
(fn [_path] (p/rejected missing-error)))})
|
||||
(p/then (fn [_]
|
||||
(let [path (page-path "pages/Page A.md")]
|
||||
(is (= "- hello" (get @files path)))
|
||||
(is (= [[path "- hello"]] @writes)))))
|
||||
(p/catch (fn [e] (is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest unexpected-mirror-file-read-error-rejects-page-mirror-test
|
||||
(async done
|
||||
(let [{:keys [platform writes]} (fake-platform)
|
||||
read-error (ex-info "permission denied" {:code :eacces})
|
||||
conn (db-test/create-conn-with-blocks
|
||||
{:pages-and-blocks [{:page {:block/title "Page A"}
|
||||
:blocks [{:block/title "hello"}]}]})
|
||||
page (db-test/find-page-by-title @conn "Page A")]
|
||||
(-> (markdown-mirror/<mirror-page!
|
||||
test-repo @conn (:db/id page)
|
||||
{:platform (assoc-in platform [:storage :read-text!]
|
||||
(fn [_path] (p/rejected read-error)))})
|
||||
(p/then (fn [_]
|
||||
(is false "Expected mirror write to reject when read fails unexpectedly")))
|
||||
(p/catch (fn [error]
|
||||
(is (= read-error error))
|
||||
(is (empty? @writes))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest page-mirror-exports-property-values-test
|
||||
(async done
|
||||
(let [{:keys [platform files]} (fake-platform)
|
||||
|
||||
Reference in New Issue
Block a user