Fork me on GitHub
#beginners
<
2023-10-31
>
Marius16:10:36

Hi all! What can be the reason for exceptions not being caught / being caught at the wrong place? I have the following code to check for DB outages, which is called by a GET handler (Ring)

(defn db-alive? []
  (try 
    (some? (db/test-db-connection))
    (catch Exception e
      (println "Caught one...")
      false)))
But instead of seeing the string printed out, the Exception is caught by the prone middleware (https://github.com/magnars/prone) . And this is what confuses me: My try/catch is “closer” to the exception (before the Ring handler response), therefore I would expect it to catch it. Why doesn’t it work like that?

seancorfield17:10:15

What is the exception that is being caught here? The m/w catches Exception but it also catches AssertionError -- which is an Error, not an Exception -- so if your db/test-db-connection fails with an assertion, your code won't catch it (and probably shouldn't -- errors are generally considered unrecoverable, exceptions can be handled).

Marius17:10:24

It’s java.net.ConnectException: Connection refused wrapped into org.postgresql.util.PSQLException and java.sql.SQLTransientConnectionException

hiredman17:10:14

and does the stacktrace for the exception point to db-alive?

hiredman17:10:37

my guess is you have something like authorization middleware that is looking at the database and throwing the exception

🔮 1
seancorfield17:10:30

Also, what version of the PG driver are you using? At one point PG's exception hierarchy was really bizarre but I think they fixed it in a later release.

Ed18:10:36

Does db/test-db-connection return a lazy sequence? If you map over a results set, for example, it may not actually get evaluated until the middleware tries serialise the http response?

Marius19:10:53

I just checked the stacktrace, @U0NCTKEV8 was right: There was indeed another authorization layer making a DB request, thus failing earlier. I checked the stacktrace but obviously not thoroughly enough. Thank you all for your help!

1
Ed21:10:39

That's one of the main thing I've learned from hanging out on this slack. @U0NCTKEV8 is always right ;)

😂 1
truestory 1
vlad_poh20:10:40

I want to use a hashmap as a function to update keys in another hashmap. I don’t want to list all the keys just the malformed ones.

(update-keys {:a 1 :B 2 :c 3} {:B :b})
;=> {nil 3, :b 2}
when i really want
(update-keys {:a 1 :B 2 :c 3} {:B :b})
;=> {:a 1 :b 2 :c 3}
Tweaking the original update-keys function to this
(defn update-keys 
  [m f]
  (let [ret (persistent!
             (reduce-kv (fn [acc k v] (assoc! acc (or (f k) k) v))
                        (transient {})
                        m))]
    (with-meta ret (meta m))))
from this
(defn update-keys 
  [m f]
  (let [ret (persistent!
             (reduce-kv (fn [acc k v] (assoc! acc (f k) v))
                        (transient {})
                        m))]
    (with-meta ret (meta m))))
works but doesn’t feel right. Is it ok to do so or should i just create a function instead of using a hashmap.

dpsutton20:10:52

(update-keys {:a 1 :B 2 :c 3} #({:B :b} % %))
{:a 1, :b 2, :c 3}

💯 1
dpsutton20:10:33

just use a function that does what you want

Nundrum20:10:38

Maybe you just want merge?

hiredman20:10:20

or clojure.set/rename-keys

6
vlad_poh20:10:38

@U11BV7MTK can you kindly explain your function

seancorfield20:10:32

(fn [k] (get {:B :b} k k) is an expanded version of Dan's function -- does that help?

vlad_poh20:10:32

@U04V70XH6 it almost does! i know get has the not-found option but how do i figure out that a hashmap does too?

seancorfield20:10:00

(my-map k :not-found) is how hash maps behave as functions... let's see if I can find the docs reference...