Skip to content

Instantly share code, notes, and snippets.

@adamrenklint
Created January 28, 2018 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamrenklint/497d6db755eba21b965ee56f610314b8 to your computer and use it in GitHub Desktop.
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
; 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))
@adamrenklint
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment