Fork me on GitHub
#clojure
<
2023-03-24
>
kennytilton11:03:13

Am I hallucinating or is this new?

WARNING: update-vals already refers to: #'clojure.core/update-vals in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/update-vals
WARNING: update-keys already refers to: #'clojure.core/update-keys in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/update-keys
Seems benign.

souenzzo11:03:40

No. this is since 1.11 just bump your core.async (usually, core.async is the one that requires the core.analyze)

kennytilton13:03:38

Hmm. Did not have core.async in there. Might have been some HTTP lib. So I dropped back to Clojure 1.10.3, raising another question: Why am I always bumping my dependencies to the latest version? My thinking is "latest/greatest yay!", but shouldn't I be shooting for "what is the oldest version against which my software will work?". ie, Doesn't an excessive dependency tell people who might need to run against an older Clojure they are out of luck? think_beret

souenzzo13:03:00

lein deps :tree | less or clj -Stree | less and search who is requiring the clojure/analyzer easy solution (i do this): just add the latest analyzer to your deps [org.clojure/tools.analyzer.jvm "1.2.3"]

souenzzo13:03:54

> Doesn't an excessive dependency tell people who might need to run against an older Clojure they are out of luck? no. it is fine to ignore those warnings. thre is no broken code or anything like that.

kennytilton16:03:26

Ah, my old buddy cljs.http 0.1.46, with no indication it will ever move forward, pulls in org.clojure/core.async "0.4.474" I could fork it I suppose and bump the async, but it is there only to support a test. Thx for the tip on lein deps :tree, I forgot about that! 🙏

souenzzo16:03:20

Again: I'd just add a core.async directly in my deps.

👍 2
kennytilton12:03:58

Damn, someday I should read the leiningen doc! 🙂 But the beauty of lein is that we can get so far without needing to.

kennytilton13:03:38

Hmm. Did not have core.async in there. Might have been some HTTP lib. So I dropped back to Clojure 1.10.3, raising another question: Why am I always bumping my dependencies to the latest version? My thinking is "latest/greatest yay!", but shouldn't I be shooting for "what is the oldest version against which my software will work?". ie, Doesn't an excessive dependency tell people who might need to run against an older Clojure they are out of luck? think_beret

folcon13:03:53

with-redefs and with-redefs-fn seem to no longer function? Compared to: https://clojuredocs.org/clojure.core/with-redefs#example-542692d6c026201cdc3270bc

(with-redefs [type (constantly java.lang.String)
                class (constantly 10)]
    [(type [])
     (class [])])
=> [clojure.lang.PersistentVector clojure.lang.PersistentVector]
Anyone else noticed this? This could be related to running OpenJDK 19?

pavlosmelissinos14:03:22

Works for me

$  java --version
openjdk 19.0.2 2023-01-17
OpenJDK Runtime Environment (Red_Hat-19.0.2.0.7-1.rolling.fc37) (build 19.0.2+7)
OpenJDK 64-Bit Server VM (Red_Hat-19.0.2.0.7-1.rolling.fc37) (build 19.0.2+7, mixed mode, sharing)

$ clj
Clojure 1.11.1
(with-redefs [type (constantly java.lang.String)
                class (constantly 10)]
    [(type [])
     (class [])])
[java.lang.String 10]

borkdude14:03:53

@U0JUM502E Do you by any chance have direct linking enabled?

borkdude14:03:39

$ clj -J-Dclojure.compiler.direct-linking=true
Clojure 1.10.3
(with-redefs [type (constantly java.lang.String)
                class (constantly 10)]
    [(type [])
     (class [])])
[clojure.lang.PersistentVector clojure.lang.PersistentVector]

☝️ 2
folcon16:03:09

Oh ok, yes. Thanks @U04V15CAJ! I've lifted that into the prod profile 😃...

borkdude16:03:58

Even in prod this can bite you, if you like to REPL into production and patch things here and there, just something to be aware of :)

folcon16:03:50

Fair point, for this project it's not viable, but good to be aware 😉...

ghadi14:03:14

that's not the result I get, Corretto 19

folcon14:03:15

Hmm, ok, that's puzzling then

Thierry14:03:45

I have a general question about clojure.test with lein test and Exceptions being omitted, any replies would be nice, thanks in advance! The project I work on relies on mount.lite for state management and uses taoensso.timbre for logging. The test scenario handling (made by someone other then myself in the past) starts the state-management for each scenario by using use-fixtures , so far so good. test works fine. But, I have been scratching my head about one test stopping halfway all day. No error is thrown and the process it should run just stops and state-management stops all started parts and the test ends in a fail without any clues. I found out that when an Exception is thrown by timbre, this Exception is never printed or logged and the test run just stops. The following example is exactly what happens and what Exception should be thrown, it just never gets thrown.

(taoensso.timbre/debugf "my % father %s is %s" "living" "john" "nextdoor")
; Execution error (IllegalFormatConversionException) at java.util.Formatter$FormatSpecifier/failConversion (Formatter.java:4442).
; f != java.lang.String
If I execute the above in a repl inside the project, the Exception gets thrown as expected. In the unit test its omitted/ignored, the process does stop as if an Exception was thrown but the Exception isnt printed. What could cause this? I am running this on Leiningen 2.10.0, Clojure 1.11.1 and Java17

dpsutton14:03:35

"my *%* father %s is %s" "living" That first % needs to be %s . You have an invalid format string

dpsutton14:03:47

user=> (taoensso.timbre/debugf "my % father %s is %s" "living" "john" "nextdoor")
Execution error (IllegalFormatConversionException) at java.util.Formatter$FormatSpecifier/failConversion (Formatter.java:4442).
f != java.lang.String

Thierry14:03:53

I know what the issue is, thanks

dpsutton14:03:54

user=> (taoensso.timbre/debugf "my %s father %s is %s" "living" "john" "nextdoor")
2023-03-24T14:52:03.385Z  DEBUG [user:1] - my living father john is nextdoor

Thierry14:03:17

My question is why the Exception is omitted in lein test

dpsutton14:03:28

ah apologies

Thierry14:03:34

no problem 🙂

dpsutton14:03:39

are there multiple threads involved?

Thierry14:03:15

multiple thread, not concurrent, but uses ThreadPoolExecutor

Thierry14:03:04

At first I though it might be because the reduce function its in has side effects, but other side effects get logged / executed just fine.

dpsutton14:03:31

my guess is the thread you expect to produce a value dies and your test harness is still expecting a value to come from that thread?

Thierry14:03:14

It's just the Exception that doesn't get printed/logged when using lein test but does get logged when running the project

hiredman16:03:12

Is the exception coming from test code or from the fixture?

hiredman16:03:12

Fixtures can behave oddly if exceptions bubble out of them

hiredman16:03:05

(whatever weirdness with exceptions and fixtures I think I recall may have been fixed)

Thierry16:03:29

The Exception should be thrown by the mentioned debugf from timbre, but isn't. Or atleast, it is probably thrown but not shown or printed or logged anywhere

Thierry16:03:12

If Kondo would pick up the incomplete formatter I would have found it sooner tho 🙂

Thierry16:03:19

will see if I can enable this somehow

Thierry16:03:25

still strange the Exception isnt thrown tho

hiredman16:03:18

oh, the exception is almost certainly thrown

Thierry16:03:44

You are indeed right, it's just not logged/printed anywhere

hiredman16:03:30

you might have an uncaught exception handler or something in production that logs things

Thierry16:03:34

thing is, if I forcefully create something that should thrown an Exception anywhere in the process, the Exception gets thrown like it should

Thierry16:03:52

thrown and logged/printed I mean

Thierry16:03:15

this specific Exception just isnt logged/printed in the unittest, but is when manually testing the process

hiredman16:03:58

are you sure in your tests to force an exception you are doing that on the same thread where the bad logging statement would be run?

Thierry16:03:41

I think I am, but I will check again

Thierry16:03:40

I tried testing the separate process function and it does print/log the thrown Exception. But if I wrap the function in a clojure.core.async/thread it's not printed in my repl but I get a message in the Calva terminal:

Exception: clojure.lang.ExceptionInfo thrown from the UncaughtExceptionHandler in thread "async-thread-macro-1"

Thierry16:03:57

The process isnt run in core.async thread tho

hiredman17:03:07

sure, but it is run in another thread, how is that other thread started?

hiredman17:03:23

you're running your own threadpool?

hiredman17:03:02

how do you know the faulty logging is actually being run?

hiredman17:03:17

are you waiting for the thread it runs on to complete?

Thierry17:03:33

If I run the process without lein test with a subset of data the process gets queued using these imports:

[clojure.lang Var]
[java.util.concurrent ConcurrentHashMap Executors RejectedExecutionException]
[java.util.function Function]
The faulty logging gets executed and throws the Exception

Thierry17:03:12

When I use the unittest the statemanagement stops the process due to the internal Exception handler catching it, what it does otherwise aswell

Thierry17:03:19

its just not printed during the unit test

hiredman17:03:14

when you run the processs outside of testing, does the process hang around after the exception is printed out?

Thierry17:03:07

If I do this manually using async/thread it does and I need to interrupt evaluation. It doesn't when testing the process using test data in a live non production environment

Thierry17:03:32

its just strange it doesnt get logged. the issue is solved, but for faster debugging it would be a nice to have haha

hiredman17:03:42

I would try putting a sleep of a few seconds in before the statemanagement stuff stops anything

hiredman17:03:38

not as a fix or anything, but just to see if that causes whatever to get printed / logged

hiredman17:03:11

to be clear you expect it to be logged or printed? (going out through print/prn or out through timbre)

hiredman17:03:59

I seem to recall timbre failing to flush the stream it is writing to, so you can lose log messages on exit that way (but haven't used timbre in a while, and when I did it drove me nuts so I might be misremembering it unfavorably)

Thierry17:03:28

Out through timbre

hiredman17:03:06

you might also add a class to (flush) before the statemanagement stuff tears things down

Thierry17:03:22

The statemanagement is run by a fixture in the unitest. Ill add the flush there. Might be that is what's not logging the exception as its a try with finally and no catch

Thierry11:03:35

I can get the Exception to be logged/printed if I wrap the formatting line that causes the error in a separate try catch block

Thierry11:03:51

some somewhere its not catching it properly to be thrown back to the test run

Thierry12:03:59

I've found the source of the issue. The function that formats the log output is the culprit. I've added a try catch there and now the error and stacktrace get nicely logged