Clojurians
#nrepl
<
2018-04-20
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

shawx53819:04:47

Heyo. I have a question. it seems that the view of messages in nREPL varies depending on whether I looking at them from a middleware, or from a client

shawx53819:04:30

I'm trying to write a function that takes a piece of code as a string and evaulates it, returning all nREPL messages related to it's evauluation

shawx53819:04:49

And for standard responses, it's fine

shawx53819:04:17

But anything sent to err or out doesn't seem to arrive on the client side

shawx53819:04:56

Which is unfortunate, because I am trying to write code for modifying error messages, and those don't show up

hiredman20:04:31

*err* and *out* are thread local bindings, so writing to them will depend on what thread the writing to is occuring on

hiredman20:04:39

if in your server process you are spinning up some thread that somehow doesn't copy the repls values of *err* and *out* it will get the default values and nrepl won't be able to capture the output

shawx53820:04:17

So this is what I have.

(defn trap-response [inp-code]
(with-open [conn (repl/connect :port server-port)]
     (-> (repl/client conn 1000)
       (repl/message {:op :eval :code inp-code})
       doall)))

shawx53820:04:32

With some code to start an nREPL server preceding it

shawx53820:04:06

In the middleware I am trying to test, I know that

:err
exists

shawx53820:04:19

how can I copy the repl values of

*err*
?

hiredman20:04:25

it will depend on what you are running and what inp-code is doing

hiredman20:04:07

e.g. a new thread launched with say future does automatically inherit the initiating threads values of err and out (also any other dynamic vars bound)

hiredman20:04:06

if you are manually creating and starting a Thread object you will have do it yourself, the easiest way is likely to use bound-fn

shawx53820:04:41

for the present I am not doing anyhting threaded

hiredman20:04:47

oh, are you saying your middleware is seeing the messages with :err in them?

shawx53820:04:11

My middleware is attempting to improve java error messages

hiredman20:04:15

just somewhere between your middleware and the client the message is getting dropped

hiredman20:04:44

is your middleware forwarding on the message correctly? is it throwing an error causing the error message to be swallowed?

shawx53820:04:51

Yeah, and the error message comes through, but as a print, and not in right place

hiredman20:04:10

what do you mean "as a print" and "not in the right place" ?

shawx53820:04:42

Okay, so I run trap response and I get a list of nrepl messages back

shawx53820:04:59

But it also prints the modified error message

shawx53820:04:04

so I get something like

shawx53820:04:12

teardown.core=> (trap-response "(banana)")
Name banana is undefined.
({:ex "class clojure.lang.Compiler$CompilerException", :id "a71b6465-6515-4b66-801c-91daa498cdf8", :root-ex "class clojure.lang.Compiler$CompilerException", :session "50e928a8-2fed-44c9-adae-8404972586f1", :status ["eval-error"]} {:id "a71b6465-6515-4b66-801c-91daa498cdf8", :session "50e928a8-2fed-44c9-adae-8404972586f1", :status ["done"]})
teardown.core=> 

hiredman20:04:43

oh, that isn't :err

hiredman20:04:59

that is :ex , the exception value

hiredman20:04:21

status :eval-error

hiredman20:04:58

that isn't output to *out* or *err*, that is the error result of the eval

shawx53820:04:00

I would like to see an entry in my list of responses with that key

hiredman20:04:20

are you just printing the message in your middleware?

hiredman20:04:43

what does trap-response do?

hiredman20:04:12

and what does your middleware do? are you running the repl server in the same jvm as you are running trap-response?

shawx53820:04:50

my middleware takes the value of :err and changes it. Eventually I hope to gain access to the exception object, but for the moment I am parsing string to string

hiredman20:04:35

are you sure you aren't just printing out the string in the middleware? it looks a lot like you are

hiredman20:04:13

I am not sure that an error like that results in anything coming back with :errr set

hiredman20:04:26

I think you just get the :ex

shawx53820:04:28

no, there are no prints in my middleware

shawx53820:04:15

middleware wraps the transport function in incoming messages, so that post eval this code is run

shawx53820:04:35

(defn modify-errors "takes a nREPL response, and returns a message with the errors fixed"
  [inp-message]
  (if (contains? inp-message :err)
    (assoc inp-message :err (m-obj/get-all-text (:msg-info-obj (p-exc/process-spec-errors (inp-message :err)))))
    inp-message))

hiredman20:04:35

I am looking at the interruptible-eval middleware right now, and when an exception is thrown it doesn't set :err, you get back the :ex message

shawx53820:04:16

and yet my middleware works. I don't mean to be obtuse, but in developping the middleware I never got access to the

:ex
message

hiredman20:04:50

how recently have you restarted your repl?

shawx53820:04:28

fresh for these commands

shawx53820:04:43

Fresh everytime I touched the middleware

hiredman20:04:28

I would put in some printlns in each branch of that if to see which branch is actually getting taken

shawx53820:04:10

This is the code

shawx53820:04:30

and I know which branch is being taken, because I can see the transformed error messages

hiredman20:04:55

no, you are seeing some printlns

shawx53820:04:18

okay. I am confused but attentive

hiredman20:04:44

you are seeing some output that sort of looks like it matches what in some circumstances might match what you would get if your middelware is running

hiredman20:04:39

but that doesn't actually prove that it is, so you need to prove that it is, and prove that is running the way you expect

hiredman20:04:58

you may also have an easier time debugging this kind of thing if you run the client and the server in different jvms

shawx53820:04:17

I can do that.

shawx53820:04:46

Well, I can connect to the babel jvm

hiredman20:04:28

what do you mean by that?

shawx53820:04:17

I am unsure of how to connect to a nREPL server using the middleware

hiredman20:04:25

I mean, you have two jvms, on running an nrepl server with your middleware, a second running an nrepl server without your middleware, you nrepl into the second and run trap-response

hiredman20:04:33

(connecting to the first)

hiredman20:04:09

where you see the message printed out will tell you if it is being printed in the client side or the server side

hiredman20:04:24

it is almost certainly on the server side

shawx53820:04:47

IIRC it is, that was what I meant when I said "in the wrong place"

hiredman20:04:34

if you are satisfied that you have proved to yourself that it is printing on the server side, then you can start looking at the code being run on the server side

hiredman20:04:40

are you aot compiling?

hiredman20:04:56

what I am getting at there is, is the code you think you are running what is actually running, aot compilation can be a culprit there, but I've seen people have multiple copies of the src directory and edit the wrong one, or forget to save the file, or whatever

shawx53820:04:25

Okay, so launching one repl with middleware, connecting a second one to it, defining and running trap response in the second one gets me a modified error message and the return list of messages, both in the second repl

hiredman20:04:46

interesting

shawx53820:04:56

waitaminute.

shawx53820:04:36

trap-response launches a third repl server and sends things to it for eval

shawx53820:04:56

How but the error messages are still being modified

shawx53820:04:42

I think I see

hiredman20:04:05

my kind of vague hand wavy guess is you have state issues in your middleware stack, global state is being used, which could be a problem if you have more than one nrepl session running

shawx53820:04:21

somehow between the repl trap response runs and the one it is in, my middleware steps in

shawx53820:04:29

I don't think there is any state

hiredman20:04:53

I dunno, I see a bunch of def'ed atoms, and I made a hand wavy guess

shawx53820:04:27

sorry core has been deprecated. Those were for testing purposes, and no code runs in core now.

shawx53820:04:32

really sorry about that

hiredman20:04:57

no worries, just took a glance around

shawx53820:04:02

So, just trying out a plain old division by zero error in the repl that runs trap-response, I see it's error messages are being modified

shawx53820:04:45

https://clojurians.slack.com/archives/C17JYSA3H/p1524256604000032 though I am still concerned by any problems you saw when you said this

hiredman20:04:14

I didn't see any problems, it is more like like I try to eliminate assumptions when debugging, and that seemed like one

shawx53820:04:31

fair enough

shawx53820:04:54

AFK ~2 minutes max

shawx53821:04:52

it seems if trap-response's own server is set to point at the modified server, then I do get

:err

shawx53821:04:43

This seems to be working, and I am very grateful

shawx53821:04:53

thank you for your time and expertise