some quick notes, no answers yet, but we almost never use Float/parseFloat, or floats in general (outside of interop of other specific use cases where you are specifically controlling for space/size) like I see here, since clojure defaults to double and long types, e.g. Double/parseDouble (now in clojure 1.11 there are core functions for common parsing like parse-double ). Unless you are storing stuff in the database in this way, or interoperating with a java library that specifically uses floats, I would not recommend them. They can provide counter-intuitive equality stuff like
user=> (hash-set 1.1 (float 1.1))
#{1.1 1.1}
I don’t think it’s necessary or idiomatic to specify the version of cider in your plugins either, e.g. in project.clj, although it is unclear if you are even using cider (looks like vscode is there…)
:project/dev {:jvm-opts ["-Dconf=dev-config.edn" ]
:dependencies [[org.clojure/tools.namespace "1.2.0"]
[pjstadig/humane-test-output "0.11.0"]
[prone "2021-04-23"]
[ring/ring-devel "1.9.5"]
[ring/ring-mock "0.4.0"]]
:plugins [[com.jakemccrary/lein-test-refresh "0.24.1"]
[jonase/eastwood "0.3.5"]
[cider/cider-nrepl "0.26.0"]] ;<----maybe remove this.....
...
I can’t get the project running at the moment due to config/environment expectation mismatch. I probably need to dig into luminus more (aside from getting a repl connected). dev profile isn’t helping, etc.
regarding the observation of invoking with 2 parens, that should be meaningless, e.g.
(defn some-fn [x]
(blah x))
;;vs
(defn some-fn [x]
(blah x)
)
That sounds extremely suspect - if you think it is what is isolating a particular error.
edit - got it somewhat working, specifying the sqlite db connection and correcting the dev config (I think); enough to reproduce your error in the /test2 route, and to try stuff out at the repl:
rental.routes.home> (db/addb! {:name "Bilbo" :org "sdf" :parea 23 :barea 34 :tarea 65 :hyra 3232
:omk 4343 :tid 23 :start 43 :stop 56 :notes "notes" :kost 65 :kost2 34})
1
rental.routes.home> (->> (db/getrows) (map :name) set)
#{"noname" "Bilbo" "jonas"}
So the db layer works fine. Something is getting jacked up in the middleware.
this is the actual request map with all the middleware junk tacked on. I just changed the route for /test2 to:
(fn [req]
(pr req)
(db/addb! {:name "jonas" :org "sdf" :parea 23 :barea 34 :tarea 65 :hyra 3232
:omk 4343 :tid 23 :start 43 :stop 56 :notes "notes" :kost 65 :kost2 34}))]])
to print out the request map prior to invoking our problem function. So now we can dissect it a bit. There are prettier ways to do it (like using the cider debugger or other stuff), but this worked fine.
-Final edit
I get it now. If you look at the result of add-db
, you will notice it returns an integer. I am pretty sure this is the number of records created (or a 0/1 indicator of success, not 100% sure, need to check the docs). So you have a defined a route with some middleware on the /test2 route, that invokes this function. The problem is, the result you return from this function - 1 - is then handed off to the middleware, which is expecting (per the ring methodology) to have a hash map of all the data for the response. So you are returning 1, the ring.middleware.flash handler (which is wrapped up in your middleware somewhere in the configs), now tries to apply its work to the response map, except it’s not a map. So when it invokes contains?
against an integer, 1, we get a runtime type error. As a result the response bombs out and you get the stack error you noticed.
So the reason it “works at the REPL” but not the routing of an HTTP response, is that your handler is yielding a non-map response. I am uncertain if there is some expectation that a middleware would pick up on these values an wrap them for you, or if this is just an oversight (or learning stuff). In this case, if I change the handler to:
["/test2" (fn [req]
(do (db/addb! {:name "jonas" :org "sdf" :parea 23 :barea 34 :tarea 65 :hyra 3232
:omk 4343 :tid 23 :start 43 :stop 56 :notes "notes" :kost 65 :kost2 34})
{:status 200, :headers {}, :body "Added jonas!"}))]
I invoke the db addition as a side effect, but I return a map indicating a success response (maybe it should be 201, I am not a web dev…). In any case, if I reload the new code, and invoke user/restart to ensure the libraries (I think they are using mount) pick up all the new changes, then navigate back to /test2, I get a response and no error.
If you look at all of the other routing functions, they all return an HTTP response via the layout/render function, which is:
(defn render
"renders the HTML template located relative to resources/html"
[request template & [params]]
(content-type
(ok
(parser/render-file
template
(assoc params
:page template
:csrf-token *anti-forgery-token*)))
"text/html; charset=utf-8"))
where ok
is from the [ring.util.http-response :refer [content-type ok]] requires, so a convenience function to wrap the body in a map…
(defn ok
"200 OK (Success)
OK"
([] (ok nil))
([body]
{:status 200
:headers {}
:body body}))
I think if you remember to return response maps for these handlers (perhaps there are more sophisticated possibilities with reitit routing), then you will avoid these kinds of errors. I am unsure what the idiomatic path is to modify the db - you probably want to return a response conditioned on whether the commit actually went through.