Default printing when coercion fails is very expensive
bsless opened this issue · comments
While reitit is fast in its happy path, when coercion fails there are several paths which are extremely wasteful:
In coercion.cljc:
(defn ^:no-doc response-coercion-failed! [result coercion value request response]
(throw
(ex-info
(str "Response coercion failed: " (pr-str result))
(merge
(into {} result)
{:type ::response-coercion
:coercion coercion
:value value
:in [:response :body]
:request request
:response response}))))
pr-str
serializes the entire result which might be very large
In reitit/coercion/malli
(-encode-error [_ error]
(cond-> error
(show? :humanized) (assoc :humanized (me/humanize error {:wrap :message}))
(show? :schema) (update :schema edn/write-string opts)
(show? :errors) (-> (me/with-error-messages opts)
(update :errors (partial map #(update % :schema edn/write-string opts))))
returning the schema and errors by default and serializing them to edn string is also very slow and expensive.
Should these be off by default?
I think they should. It's a breaking change, but for the better.
So proposed changes:
- remove
:schema
and:errors
from default coercion error keys - don't
pr-str
result
in{response,request}-coercion-failed!
by default, add option to do so?