Hi, I'm new to Clojure and Pedestal. I was having this error when executing a "get-user-by-id" sql query, cause my id param was passed as a String, and my id field type is a integer in the postgresql database: [{:type org.postgresql.util.PSQLException ; :message "ERROR: operator does not exist: integer = character varying\n Hint: No operator matches the given name and argument types. You might need to add explicit type casts.\n Position: 296" ; :at [org.postgresql.core.v3.QueryExecutorImpl receiveErrorResponse "QueryExecutorImpl.java" 2725]}] I solved this with this interceptor (see image attached): Is this a good way to solve this error, or there is a better approach to this issue? Thanks a lot!
read-string is bad!
it allows code-injection
To read EDN, you can use clojure.edn/read-string
But in this case, I think that you should use parse-long from clojure core.
Hi Valentin,
You can use an interceptor to validate inputs in request and immediately return for invalid inputs (or coerce the inputs and continue to the next interceptor).
In your example above, you are coercing the input from string to long but consider the possibility that it might be a string "one".
And don't use read-string . it can execute code.
As ^, you don’t want read-string, arbitrary code execution, and clojure.edn/read-string is probably overly generic for this kind of a code path. There are two more idiomatic paths for parsing, depending on whether you want exception handling or nils out of a failed parse:
(Long/parseLong "A1")
;; throws
(parse-long "A1")
;; nil
Given where this probably fits in your route handling, I’d probably try or when-let to parse the long and when you hit a non-integer path param (and parsing fails), short-circuit the interceptor chain there with an error.
Thanks guys a lot! Has Pedestal a predefined interceptor that already do that? (Coercing path-params) If a define a schema for the path-params, is there a predefined Pedesral Interceptor that take this schema and coerce the path-params, like reitit do it? Thanks again!
Also, the point of an interceptor is it becomes an easy way to duplicate functionality with high accuracy … you are likely to have multiple endpoints that take a user id parameter and have to parse and validate it.
You can then unit test your handler, passing it a request (or context) that has the user id already converted to a long. This is great, as you don’t have to write endless tests for each handler to cover error cases related to the user id. This is one big advantage of composition (and interceptors are a very specialized kind of composition).