Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal Expound assertion failed using ring.core.spec #93

Closed
conan opened this issue May 14, 2018 · 6 comments
Closed

Internal Expound assertion failed using ring.core.spec #93

conan opened this issue May 14, 2018 · 6 comments
Labels

Comments

@conan
Copy link

conan commented May 14, 2018

I've written a function spec for my top-level ring handler, which is a function called app that calls reitit.ring/ring-handler. It looks like this:

(defn app
  []
  (rr/ring-handler
    ... ))

(s/fdef app :ret :ring/handler)

The :ring/handler spec is defined in ring-spec.

There's some kind of problem when I call (or s/explain the result of) this function that makes Expound throw an exception. It looks like this:

AssertionError Assert failed: Internal Expound assertion failed. Please report this bug at https://github.com/bhb/expound/issues: All values should be the same, but they are [{:path [:sync+async :fn :sync :args :request], :pred map?, :via [:ring/handler :ring.sync+async/handler :ring.sync.handler/args :ring.sync.handler/args :ring/request :ring/request], :expound/form #object[clojure.lang.AFunction$1 0x7024b79d "clojure.lang.AFunction$1@7024b79d"], :val :sync, :spec :ring/handler, :expound/path [:sync+async :fn :sync :args :request], :expound/in [], :in [:args 0], :expound/via [:ring/handler :ring.sync+async/handler :ring.sync.handler/args :ring.sync.handler/args :ring/request :ring/request]} {:path [:sync+async :fn :sync :ret], :pred map?, :via [:ring/handler :ring.sync+async/handler :ring/response], :expound/form #object[clojure.lang.AFunction$1 0x7024b79d "clojure.lang.AFunction$1@7024b79d"], :val [:async {:status 405, :body ""}], :spec :ring/handler, :expound/path [:sync+async :fn :sync :ret], :expound/in [], :in [:ret], :expound/via [:ring/handler :ring.sync+async/handler :ring/response]} {:path [:sync+async :fn :async :args :request], :pred map?, :via [:ring/handler :ring.sync+async/handler :ring.async.handler/args :ring.async.handler/args :ring/request :ring/request], :expound/form #object[clojure.lang.AFunction$1 0x7024b79d "clojure.lang.AFunction$1@7024b79d"], :val :sync, :spec :ring/handler, :expound/path [:sync+async :fn :async :args :request], :expound/in [], :in [:args 0], :expound/via [:ring/handler :ring.sync+async/handler :ring.async.handler/args :ring.async.handler/args :ring/request :ring/request]}]
(apply = (map :val problems))  expound.alpha/eval6753/fn--6754 (alpha.cljc:577)

(this is how it's formatted)

When I run without expound, I get the following output:

ExceptionInfo Call to #'hanabi.web/app did not conform to spec:
In: [:args 0] val: :sync fails spec: :ring/request at: [:ret :sync+async :fn :sync :args :request] predicate: map?
In: [:args 0] val: :sync fails spec: :ring/request at: [:ret :sync+async :fn :async :args :request] predicate: map?
In: [:ret] val: [:async {:status 405, :body ""}] fails spec: :ring/response at: [:ret :sync+async :fn :sync :ret] predicate: map?
val: {:status 405, :body ""} fails spec: :ring/response at: [:ret :sync :ret] predicate: (contains? % :headers)
val: ({:server-port 1, :server-name "", :remote-addr "", :uri "/", :scheme :http, :protocol "HTTP/1.1", :headers {}, :request-method :a} #object[clojure.spec.alpha$fspec_impl$reify__2451$fn__2454 0x49704cb9 "clojure.spec.alpha$fspec_impl$reify__2451$fn__2454@49704cb9"] #object[clojure.spec.alpha$fspec_impl$reify__2451$fn__2454 0x6859d673 "clojure.spec.alpha$fspec_impl$reify__2451$fn__2454@6859d673"]) fails spec: :ring.async/handler at: [:ret :async] predicate: (apply fn),  Assert failed: In: [0] val: {:status 405, :body ""} fails spec: :ring/response at: [:response] predicate: (contains? % :headers)

(pvalid? argspec args)
  clojure.core/ex-info (core.clj:4739)

Now I have no idea what's up with the spec or why Expound throws an exception, but clearly the raw spec formatting is preferable.

@bhb bhb added the bug label May 15, 2018
@bhb
Copy link
Owner

bhb commented May 15, 2018

@conan Thanks very much for reporting this! It appears to be a bug in Expound.

@bhb
Copy link
Owner

bhb commented Jun 24, 2018

Some changes in 0.7.1-SNAPSHOT make this slightly better - instead of giving an error, expound prints the (confusing, at least to me) error message:

-- Spec failed --------------------

  clojure.lang.AFunction/1

should satisfy

  map?

or

threw exception

  "Assert failed: -- Spec failed --------------------

    (nil)
     ^^^

  should satisfy

    map?

  -------------------------
  Detected 1 error

  (pvalid? argspec args)"

with args:

  {:server-port 1, :server-name "", :remote-addr "", :uri "/", :scheme :http, :protocol "HTTP/1.1", :headers {}, :request-method :a}, clojure.spec.alpha$fspec_impl$reify__2451$fn__2454@68558a2a, clojure.spec.alpha$fspec_impl$reify__2451$fn__2454@13848bf6

-------------------------
Detected 1 error

I'm going to leave this open until I can look into this more.

For reference, a test that reproduces the issue for me:

;; make sure to include [metosin/reitit "0.1.2"]
;; :ring/handler has lots of alternatives in the spec
;; including several possible fdef implementations
(deftest complex-alternatives
  ;; Repro without reitit
  (is (string?
       (binding [s/*explain-out* expound/printer]
         (s/explain-str :ring/handler (fn [req] {})))))

  ;; Repro with reitit
  (binding [s/*explain-out* expound/printer]
    (is (string?
         (s/explain-str :ring/handler (rr/ring-handler (rr/router ["" #(prn "")])))))))

@bhb
Copy link
Owner

bhb commented Jun 24, 2018

Hm, this may relate to over-using the internal function predicate-errors in too many places.

@bhb
Copy link
Owner

bhb commented Jun 8, 2019

Related: ring-clojure/ring-spec#7

@bhb
Copy link
Owner

bhb commented Jun 9, 2019

@conan Thanks for reporting this and sorry for the delayed fix. I've fixed this in the next branch (if you want to try it out, you can try commit e478146). Note that I've also made an improvement to the ring specs (see link above).

Thanks for using Expound!

@bhb bhb closed this as completed Jun 9, 2019
@bhb
Copy link
Owner

bhb commented Nov 25, 2019

@conan Thanks for reporting this. This fix is included in version 0.8.0, which I've just released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants