Fork me on GitHub
#calva
<
2023-10-19
>
Lidor Cohen07:10:07

Hello everyone, I asked a question at #clojurescript: https://clojurians.slack.com/archives/C03S1L9DN/p1697624121294149 and it might be calva related. the gist is that: I got an exception thrown I catch it and throw my own exception. the exception on *e is the exception I constructed. the exception that printed to the browser console is the exception I constructed. however, the exception that is printed to output.calva-repl is not my full exception, it is either the deepest :cause or the first exception that has been thrown. does anyone knows of this behavior?

pez19:10:13

Not fully following what’s going on. Can you post some example code here and tell us what the result is and what you expect it to be?

Lidor Cohen20:10:29

(try (-lookup nil :some-key)
       (catch :default e
         (throw (ex-info "My Error"
                  {:some :data}
                  e))))
I expect this to print in output.calva-repl
:repl/exception!
; 
; Execution error (ExceptionInfo) at (:1).
; My Error
or something of the sort. instead it prints:
:repl/exception!
; 
; Execution error (Error) at (:1).
; No protocol method ILookup.-lookup defined for type null: 
which is the inner exception but not my exception

Lidor Cohen20:10:46

(try (-lookup nil :some-key)
       (catch :default e
         (throw (ex-info "My Error"
                  {:some :data}))))
if I discard the cause it prints:
:repl/exception!
; 
; Execution error (ExceptionInfo) at (<cljs repl>:1).
; My Error

Lidor Cohen20:10:58

from what I gathered it is recursively dig into :cause and prints the deepest cause

Lidor Cohen20:10:26

is there a way to make it print the entire error? with data and cause?

pez20:10:31

What do you get if you evaluate *e?

Lidor Cohen21:10:32

In both cases

pez21:10:59

Is it your error you want to see?

pez21:10:49

That’s interesting… Can you try with another nrepl client? If you have Leiningen installed it is lein repl :connect from the project root directory. If you are using the Clojure CLI, this should work:

clojure -Sdeps '{:deps {reply/reply {:mvn/version "0.5.1"}}}' -M -m reply.main --attach `< .nrepl-port` 

Lidor Cohen06:10:02

I'm on cljs, does it matter or should I still do the experiment?

pez08:10:40

It’s still a Clojure REPL there. 😃 You may want to check this article out: https://blog.agical.se/en/posts/shadow-cljs-clojure-cljurescript-calva-nrepl-basics/ It also describes how you connect a command line nREPL client to the ClojureScript REPL. The reason for this experiment is to isolate where this problem could be addressed. My hypothesis is that it’s at the nREPL layer of things.

Lidor Cohen09:10:42

alright after some changes to adapt to clj:

(try (/ 4 0)
       (catch Exception e
         (throw (ex-info "My Error"
                         {:some :data}
                         e))))
The results are the same

pez09:10:46

Ah, I actually meant to do it with the ClojureScript repl, but from that prompt instead of from Calva. Seems good that you misunderstood, though, since we discover that the behavior is shared across Clojure and ClojureScript. Did you do the test from Calva or from the terminal prompt?

Lidor Cohen10:10:33

it looks like the default behavior of the REPL is diving recursively into :cause and print only the deepest cause

pez10:10:16

If we do this directly from clj we get different results, right?

pez12:10:21

Can we make some sort of comparison, focused on correct/incorrect behaviour, where correct is defined as what the plain clj and plain cljs prompts do? So, a bit like you did somewhere early in this thread: • I do A and expect X, • From the plain clj prompt I get X • From the plain clj + cljs prompt , I get … • From the nREPL Clojure prompt, … • From the nREPL ClojureScript prompt, … If we already at the nREPL level do not get X, then we know where to bring the issue. (Which might be known already by the #C17JYSA3H folks, for all I know). If the nREPL prompt says X about it, and Calva says something else, then we need to look at it in the Calva code. I doubt that, though, because Calva is a pretty plain nREPL client. It prints what the nREPL server gives it without any massaging.

Lidor Cohen13:10:50

Yeah, while doing the experiments with you I realized this is just the default behavior of clj. I asked for help in cljs first because I thought there might be some way to customize that behavior (I still believe there is) but the exchange there, led me here by mistake...

pez13:10:55

I’m not convinced it was a mistake. 😃 A thing you can test is the command Fire up a ClojureScript Quick Start Node REPL, which removes shadow-cljs from the picture.

Lidor Cohen13:10:55

If it is the behavior of clj I'm not sure what role shadow plays here. it is the same behavior from the barest of clj to cljs+shadow+calva. It is just the behavior of the repl

pez13:10:37

Ah, then I have completely misunderstood the whole thing. 😃

pez13:10:05

But seems that even so, I managed to help you. 😃 Because you understood the thing, I guess.

Lidor Cohen13:10:23

You sure have 🙏

pez13:10:04

Anyway, it can be a fun exercise. If you start that Quick Start REPL, and look at the Jack-in command used. You can then start a plain cljs prompt something like so:

❯ cd  /var/folders/t5/gqxhj8pd6p9_tnvy6sbtmy480000gn/T/betterthantomorrow.calva/h9fk9k

/var/folders/t5/gqxhj8pd6p9_tnvy6sbtmy480000gn/T/betterthantomorrow.calva/h9fk9k 
❯ ls
deps.edn        src

/var/folders/t5/gqxhj8pd6p9_tnvy6sbtmy480000gn/T/betterthantomorrow.calva/h9fk9k 
❯ ls src
hello_world

/var/folders/t5/gqxhj8pd6p9_tnvy6sbtmy480000gn/T/betterthantomorrow.calva/h9fk9k 
❯ clj -M -m cljs.main --repl-env node
ClojureScript 1.10.758
cljs.user=> 
I think it’s good to know these things, to be able to cut through the various levels of tooling.

Lidor Cohen13:10:12

You are right, when I asked in the cljs channel I assumed I'm asking about something wildly known (exceptions in the REPL) and I would get an immediate answer of the sort: "yeah that's just how the repl prints exceptions but you can change that with..."). But as the slack exchange got involved I got caught up in it and neglected doing my own investigations finding the root cause.

pez13:10:17

I’m glad you brought it here, because major TIL for me.

😊 1
ChillPillzKillzBillz14:10:03

What is the correct process? If I have updated my deps.edn with new libraries, how can I reset the calva repl so that the new libraries get downloaded/added to the project before reps gets connected?

seancorfield16:10:43

That should happen automatically when you restart the REPL.

seancorfield16:10:20

If you jack-in again -- ctrl+alt+c ctrl+alt+j -- it will kill the old REPL and start a new one.

ChillPillzKillzBillz10:10:35

Ok. After a lot of experimentation I figured out the issue on calva. If I don't choose the :build setting in the window below it all works fine. I am sure I am being an idiot somehow. But it is all working.

seancorfield16:10:40

Because the :build alias replaces the deps on the classpath, so you don't have the project deps. That's expected behavior: the build process should run without any of the project libraries or code.

ChillPillzKillzBillz07:10:10

Is there a guide which explains the consequences of choosing each of these options?

seancorfield16:10:13

Choosing which options?

seancorfield16:10:05

You don't want the :run-x alias selected, although that is "harmless".

seancorfield16:10:27

In general, in Calva you want to select aliases that create the classpath you need for the work you'll be doing with the REPL, for evaluating code you'll be editing - so you have to understand what the aliases in your project do.

Michael Brennan18:10:06

I’m using Calva with VSCode on Windows 11 and am running issues using the (read-line) in the REPL. Anytime I run it it gives an “undefined symbol” error. Running (read-line) in a regular Clojure repl (using the clj command) works fine. I’m very much a beginner to Clojure so I’m not really what I should troubleshoot/do. Any help? Thanks

pez18:10:56

So, what should happen when you evaluate (read-line) is that you should get an input box and what you submit there should be the result of the expression. Can you try it with the Getting Started REPL and see if that works?

Michael Brennan22:10:09

Getting started repl works, just not my project one.

Michael Brennan22:10:17

I'm doing the Jack-in command with joyride

pez22:10:39

Ah. I don’t think read-line exists in Joyride. Since it doesn’t exist in ClojureScript. You can use the VS Code API, maybe?

(p/let [input (vscode/window.showInputBox)]
  (when input
    (def input input)
    (println input)))
(`p` is promesa.core)