nextjournal / clerk

⚡️ Moldable Live Programming for Clojure

Home Page:https://clerk.vision

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exceptions are not shown when watcher uses filter-fn

zampino opened this issue · comments

When the watcher is started with a filter function e.g.

(clerk/serve! {:watch-paths ["notebooks" "src"] 
               :show-filter-fn #(clojure.string/starts-with? % "notebooks")})

when a notebook file is changed and contains e.g syntax or runtime errors then no exception is reported in the browser and the progress bar is stuck in analyzing state.

This happens (again) because of an unreadable expression is sent to the client as part of the document attached to the ex-data. This time, it is the printed value for the :show-filter-fn option:

{:type :set-state!,
 :doc {:path [],
       :nextjournal/value 
       {:toc {:path [], 
              :nextjournal/value […]}, 
        :error {:path [], 
                :nextjournal/value
                {:via [{:type clojure.lang.ExceptionInfo,
                        :message "`nextjournal.clerk/show!` encountered an eval error with: `\"notebooks/how_clerk_works.clj\"`",
                        :data {:nextjournal.clerk/doc
                               {:toc:footnotes []
                                :instance #object[org.httpkit.server.HttpServer 0x71c2782 "org.httpkit.server.HttpServer@71c2782"]
                                :git/url "https://github.com/nextjournal/clerk"
                                :blob->result {…}
                                :file "notebooks/how_clerk_works.clj"
                                :port 7777
                                :title "How Clerk Works 🕵🏻‍♀️"
                                :git/sha "b12aad2afe45690ecfd1b2619025cb0fab2dc77f"
                                :nav-path "notebooks/how_clerk_works"
                                :host "localhost"
                                :watch-paths ["notebooks" "src"]
                                :file-path "notebooks/how_clerk_works.clj"
                                :blocks […]

                                :show-filter-fn #function[user/eval60926/fn--60927]}}

                        :at [nextjournal.clerk$show_BANG_$fn__60588 invoke "clerk.clj" 74]} 

                       {:type clojure.lang.ExceptionInfo, :message "Execution error (ArithmeticException) at how-clerk-works/eval61174 (how_clerk_works.clj:11).\nDivide by zero\n", 
                        :data {:clojure.error/cause "Divide by zero", :clojure.error/phase :execution, :clojure.error/symbol how-clerk-works/eval61174, :clojure.error/line 11, :clojure.error/class java.lang.ArithmeticException, :clojure.error/source "how_clerk_works.clj", :line 11, :col 1, :clojure.core/eval-file "notebooks/how_clerk_works.clj", :form (/ 1 0)}, :at [nextjournal.clerk.eval$eval_PLUS_cache_BANG_ invokeStatic "eval.clj" 156]}], :trace [["nextjournal.clerk.eval/eval+cache!" invokeStatic "eval.clj" 156] ["nextjournal.clerk.eval/eval+cache!" invoke "eval.clj" 123] ["nextjournal.clerk.eval/read+eval-cached" invokeStatic "eval.clj" 195] ["nextjournal.clerk.eval/read+eval-cached" invoke "eval.clj" 166] ["nextjournal.clerk.eval/eval-analyzed-doc/fn--15710" invoke "eval.clj" 237] ["clojure.lang.PersistentVector" reduce "PersistentVector.java" 345] ["clojure.core/reduce" invokeStatic "core.clj" 6899] ["clojure.core/reduce" invoke "core.clj" 6882] ["nextjournal.clerk.eval/eval-analyzed-doc" invokeStatic "eval.clj" 230] ["nextjournal.clerk.eval/eval-analyzed-doc" invoke "eval.clj" 227] ["nextjournal.clerk.eval/+eval-results" invokeStatic "eval.clj" 258] ["nextjournal.clerk.eval/+eval-results" invoke "eval.clj" 251] ["nextjournal.clerk/show!/fn--60588/fn--60589" invoke "clerk.clj" 72] ["nextjournal.clerk/show!/fn--60588" invoke "clerk.clj" 71] ["nextjournal.clerk/show!" invokeStatic "clerk.clj" 71] ["nextjournal.clerk/show!" invoke "clerk.clj" 23] ["nextjournal.clerk/show!" invokeStatic "clerk.clj" 36] ["nextjournal.clerk/show!" invoke "clerk.clj" 23] ["nextjournal.clerk/file-event" invokeStatic "clerk.clj" 127] ["nextjournal.clerk/file-event" invoke "clerk.clj" 117] ["nextjournal.clerk/serve!/fn--60665" invoke "clerk.clj" 486] ["nextjournal.beholder/fn/reify--433" onEvent "beholder.clj" 13] ["io.methvin.watcher.DirectoryWatcher" onEvent "DirectoryWatcher.java" 402] ["io.methvin.watcher.DirectoryWatcher" runEventLoop "DirectoryWatcher.java" 349] ["io.methvin.watcher.DirectoryWatcher" lambda$watchAsync$1 "DirectoryWatcher.java" 232] ["java.util.concurrent.CompletableFuture/AsyncSupply" run "CompletableFuture.java" 1768] ["java.util.concurrent.CompletableFuture/AsyncSupply" exec "CompletableFuture.java" 1760] ["java.util.concurrent.ForkJoinTask" doExec "ForkJoinTask.java" 387] ["java.util.concurrent.ForkJoinPool/WorkQueue" topLevelExec "ForkJoinPool.java" 1312] ["java.util.concurrent.ForkJoinPool" scan "ForkJoinPool.java" 1843] ["java.util.concurrent.ForkJoinPool" runWorker "ForkJoinPool.java" 1808] ["java.util.concurrent.ForkJoinWorkerThread" run "ForkJoinWorkerThread.java" 188]], :cause "Execution error (ArithmeticException) at how-clerk-works/eval61174 (how_clerk_works.clj:11).\nDivide by zero\n", :data {:clojure.error/cause "Divide by zero", :clojure.error/phase :execution, :clojure.error/symbol how-clerk-works/eval61174, :clojure.error/line 11, :clojure.error/class java.lang.ArithmeticException, :clojure.error/source "how_clerk_works.clj", :line 11, :col 1, :clojure.core/eval-file "notebooks/how_clerk_works.clj", :form (/ 1 0)}}, :nextjournal/viewer {:name nextjournal.clerk.viewer/throwable-viewer, :render-fn #viewer-fn nextjournal.clerk.render/render-throwable, :hash "5dswADQUY2mBAupUjWd93PhFE3QG5s"}}}

       :nextjournal/viewer {:name nextjournal.clerk.viewer/notebook-viewer, :render-fn #viewer-fn nextjournal.clerk.render/render-notebook, :hash "5dsiHybTyGGTEpReRaV7nfNxoDgnKx"}}}

Does it make sense to have the whole clerk/serve! options be attached to the document? Or shall we actually control how functions get printed to EDN?