I have Clojure code and evaluate it, and then intern it into a var:
(let [x (binding [*ns* my-ns] (eval m-code))]
(intern my-ns my-sym x)) ; my-sym was declared beforehand.
But when an error occurs within x, the trace makes no reference to x:
my-ns/eval27298/fn--27299
...
I duplicated the metadata of a more "standard" var, but this does not change the stack trace:
(alter-meta! my-var #(assoc % :line 1 :column 1 :file "my_ns.clj" :name my-sym :ns my-ns))
If not the metadata, what is used to determine the stack trace?
Unless I'm mistaken, here's how it works:
Given that, alter-meta!
cannot work because all the locations have already been processed and remembered. What can work is assigning the metadata between the steps 1 and 2 above:
user=> (def code "#(throw (ex-info \"\" {}))")
#'user/code
user=> (def f (eval (-> (read-string code) (with-meta {:line 42, :clojure.core/eval-file "hello.clj"}))))
#'user/f
user=> (f)
Execution error (ExceptionInfo) at user/eval175$fn (hello.clj:42).
Note that I'm using :clojure.core/eval-file
to specify the file instead of just :file
.