reitit icon indicating copy to clipboard operation
reitit copied to clipboard

ClassCastException on invalid request with Malli coercion

Open kennyjwilli opened this issue 3 years ago • 0 comments

I am calling reitit.coercion/coerce-request and receiving a ClassCastException instead of an ExceptionInfo with request coercion failed information. The below repro was extracted from a regular Reitit handler with interceptor setup.

Environment

metosin/malli {:mvn/version "0.5.1"}
metosin/reitit {:mvn/version "0.5.13"}
(require '[muuntaja.core :as muuntaja] 'reitit.coercion 'reitit.coercion.malli)

History

(reitit.coercion/coerce-request
  (reitit.coercion/request-coercers
    reitit.coercion.malli/coercion
    {:body [:vector
            [:map [:TagKey :string]]]}
    {})
  (->> {:request-method :post
        :uri            "/foo"
        :headers        {"content-type" "application/json"
                         "accept"       "application/json"}
        :body           "[\"foo\"]"}
    (muuntaja/negotiate-request-response muuntaja/instance)
    (muuntaja/format-request muuntaja/instance)))
Execution error (ClassCastException) at malli.transform/strip-extra-keys-transformer$fn$fn (transform.cljc:367).
class java.lang.Character cannot be cast to class java.util.Map$Entry (java.lang.Character and java.util.Map$Entry are in module java.base of loader 'bootstrap')

Expectation

Calling coerce-request throws an ExceptionInfo saying that "Request coercion failed" and contains the Malli errors list.

Actual

Calling coerce-request throws a ClassCastException on reitit code. See full stacktrace below.

       nrepl.middleware.interruptible-eval/evaluate/fn  interruptible_eval.clj:   91
                                     clojure.core/eval                core.clj: 3214
                                                   ...                              
                           compute.http-api/eval107885            http_api.clj:  142
                        reitit.coercion/coerce-request           coercion.cljc:  111
                                clojure.core/reduce-kv                core.clj: 6856
                           clojure.core.protocols/fn/G           protocols.clj:  175
                                       clojure.core/fn                core.clj: 6830
                                   clojure.core/reduce                core.clj: 6828
                           clojure.core.protocols/fn/G           protocols.clj:   13
                             clojure.core.protocols/fn           protocols.clj:   75
                    clojure.core.protocols/iter-reduce           protocols.clj:   49
                                    clojure.core/fn/fn                core.clj: 6840
                     reitit.coercion/coerce-request/fn           coercion.cljc:  113
                    reitit.coercion/request-coercer/fn           coercion.cljc:   84
                     reitit.coercion.malli/-coercer/fn              malli.cljc:   60
reitit.coercion.malli/-coercer/->coercer/reify/-decode              malli.cljc:   45
                                  malli.core/-guard/fn               core.cljc:  203
          malli.core/-collection-schema/reify/reify/fn               core.cljc:  863
                                     clojure.core/into                core.clj: 6899
                                clojure.core/transduce                core.clj: 6883
                                                   ...                              
                                clojure.core/map/fn/fn                core.clj: 2742
    malli.transform/strip-extra-keys-transformer/fn/fn          transform.cljc:  367
                                   clojure.core/reduce                core.clj: 6828
                           clojure.core.protocols/fn/G           protocols.clj:   13
                             clojure.core.protocols/fn           protocols.clj:   75
                    clojure.core.protocols/iter-reduce           protocols.clj:   49
                                                   ...                              
java.lang.ClassCastException: class java.lang.Character cannot be cast to class java.util.Map$Entry (java.lang.Character and java.util.Map$Entry are in module java.base of loader 'bootstrap')

Impact

A caller calling the server with an invalid request will receive a 500 internal server error response since an unhandled exception was thrown.

kennyjwilli avatar May 06 '21 15:05 kennyjwilli