Created
January 28, 2018 14:48
-
-
Save adamrenklint/497d6db755eba21b965ee56f610314b8 to your computer and use it in GitHub Desktop.
Not able to inspect state at breakpoint after re-defining function in REPL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Consider the following code: | |
(ns debugger-demo.core) | |
(defn init [] | |
(let [a (+ 1 2 3)] | |
(js-debugger))) | |
; Reload the page and let the Dirac REPL connect | |
; We'll immediately stop at the breakpoint, and by going into the namespace we can inspect the state of the frame at which we have stopped | |
cljs.user > (require 'debugger-demo.core) | |
cljs.user > (in-ns 'debugger-demo.core) | |
debugger-demo.core > a | |
< 6 | |
; But it's easy to break this. First, press play to continue exection. | |
; And then, let's re-define the init function: | |
debugger-demo.core > (defn init [] | |
(let [a (+ 1 2 5)] | |
(js-debugger))) | |
; Then call the init function to stop at the breakpoint and try to inspect the state: | |
debugger-demo.core > (init) | |
debugger-demo.core > a | |
; We never get a response in the REPL client, and we see the following error in the REPL server: | |
SEVERE: Unhandled REPL handler exception processing message {:code a, :dirac short-circuit-presentation, :id 25, :op eval, :scope-info {:frames [{:props [{:name a}], :title Local}]}, :session 48a3efd0-b8f3-4a08-9e64-20d92b89ac27} | |
java.lang.AssertionError: Assert failed: promise-new-client-response! previous response promise pending | |
(nil? (clojure.core/deref response-promise-atom) | |
at dirac.lib.weasel_server$promise_new_client_response_BANG_.invokeStatic(weasel_server.clj:141) | |
at dirac.lib.weasel_server$promise_new_client_response_BANG_.invoke(weasel_server.clj:137) | |
at dirac.lib.weasel_server$request_eval.invokeStatic(weasel_server.clj:198) | |
at dirac.lib.weasel_server$request_eval.doInvoke(weasel_server.clj:197) | |
at clojure.lang.RestFn.invoke(RestFn.java:442) | |
at dirac.lib.weasel_server.WeaselREPLEnv._evaluate(weasel_server.clj:50) | |
at cljs.repl$evaluate_form.invokeStatic(repl.cljc:518) | |
at cljs.repl$evaluate_form.invoke(repl.cljc:452) | |
at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:853) | |
at cljs.repl$repl_STAR_.invoke(repl.cljc:760) | |
at dirac.nrepl.eval$eval_in_cljs_repl_BANG_$start_repl_fn__25076.invoke(eval.clj:245) | |
at dirac.nrepl.driver$wrap_with_driver.invokeStatic(driver.clj:142) | |
at dirac.nrepl.driver$wrap_with_driver.invoke(driver.clj:126) | |
at dirac.nrepl.eval$eval_in_cljs_repl_BANG_.invokeStatic(eval.clj:249) | |
at dirac.nrepl.eval$eval_in_cljs_repl_BANG_.doInvoke(eval.clj:212) | |
at clojure.lang.RestFn.invoke(RestFn.java:758) | |
at dirac.nrepl.utils$evaluate_BANG__STAR_.invokeStatic(utils.clj:134) | |
at dirac.nrepl.utils$evaluate_BANG__STAR_.invoke(utils.clj:122) | |
at dirac.nrepl.utils$evaluate_BANG_.invokeStatic(utils.clj:148) | |
at dirac.nrepl.utils$evaluate_BANG_.invoke(utils.clj:145) | |
at dirac.nrepl.piggieback$handle_eval_message_BANG_.invokeStatic(piggieback.clj:63) | |
at dirac.nrepl.piggieback$handle_eval_message_BANG_.invoke(piggieback.clj:60) | |
at dirac.nrepl.piggieback$handle_nonspecial_nonjoined_message_BANG_.invokeStatic(piggieback.clj:77) | |
at dirac.nrepl.piggieback$handle_nonspecial_nonjoined_message_BANG_.invoke(piggieback.clj:70) | |
at dirac.nrepl.piggieback$handle_nonspecial_message_BANG_.invokeStatic(piggieback.clj:85) | |
at dirac.nrepl.piggieback$handle_nonspecial_message_BANG_.invoke(piggieback.clj:80) | |
at dirac.nrepl.piggieback$handle_message_BANG_.invokeStatic(piggieback.clj:92) | |
at dirac.nrepl.piggieback$handle_message_BANG_.invoke(piggieback.clj:87) | |
at dirac.nrepl.piggieback$handler_job_BANG_.invokeStatic(piggieback.clj:97) | |
at dirac.nrepl.piggieback$handler_job_BANG_.invoke(piggieback.clj:94) | |
at dirac.nrepl.piggieback$dirac_nrepl_middleware_handler.invokeStatic(piggieback.clj:106) | |
at dirac.nrepl.piggieback$dirac_nrepl_middleware_handler.invoke(piggieback.clj:102) | |
at clojure.core$partial$fn__5561.invoke(core.clj:2616) | |
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__7890.invoke(middleware.clj:22) | |
at clojure.tools.nrepl.middleware.pr_values$pr_values$fn__8089.invoke(pr_values.clj:22) | |
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__7890.invoke(middleware.clj:22) | |
at boot.repl_server$wrap_init_vars$fn__8397$fn__8399.invoke(repl_server.clj:35) | |
at clojure.tools.nrepl.middleware.session$session$fn__8241.invoke(session.clj:192) | |
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__7890.invoke(middleware.clj:22) | |
at clojure.tools.nrepl.server$handle_STAR_.invokeStatic(server.clj:19) | |
at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:16) | |
at clojure.tools.nrepl.server$handle$fn__8314.invoke(server.clj:28) | |
at clojure.core$binding_conveyor_fn$fn__5476.invoke(core.clj:2022) | |
at clojure.lang.AFn.call(AFn.java:18) | |
at java.util.concurrent.FutureTask.run(FutureTask.java:266) | |
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) | |
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) | |
at java.lang.Thread.run(Thread.java:745)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A solution is to save the file where the updated
init
function is defined, triggering a reload/code injection via figwheel/boot-reload/boot-figreload. The next time we call(init)
, it behaves exactly as the first run.