Closed
Description
Passing a middleware which requires additional arguments (besides the handler) to the context*
:middlewares
metadata throws a compilation error.
I made a easy to replicate example using the lein new compojure-api command. The main file contains the following code:
(ns middlewares-issue.handler
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[schema.core :as s]))
(s/defschema Message {:message String})
(defn mw-with-args [handler msg]
(fn [request]
(let [request (assoc request :dummy msg)]
(handler request))))
(defn mw-wo-args [handler]
(fn [request]
(let [request (assoc request :foo "bar")]
(handler request))))
(defapi app
(swagger-ui)
(swagger-docs
{:info {:title "Middlewares-issue"
:description "Compojure Api example"}
:tags [{:name "hello", :description "says hello in Finnish"}]})
(context* "/hello" []
:tags ["hello"]
:middlewares [(mw-with-args "dummy")]
(GET* "/" {:as request}
(ok (str (:dummy request) " " (:foo request))))))
Then, executing lein ring server-headless throws the following error:
Exception in thread "main" clojure.lang.ArityException: Wrong number of args (-3) passed to: handler/dummy-mw, compiling:(middlewares_issue/handler.clj:30:1)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6730)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyze(Compiler.java:6485)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3791)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6725)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6711)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.access$300(Compiler.java:38)
at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:577)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6723)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyze(Compiler.java:6485)
at clojure.lang.Compiler.eval(Compiler.java:6786)
at clojure.lang.Compiler.load(Compiler.java:7227)
at clojure.lang.RT.loadResourceScript(RT.java:371)
at clojure.lang.RT.loadResourceScript(RT.java:362)
at clojure.lang.RT.load(RT.java:446)
at clojure.lang.RT.load(RT.java:412)
at clojure.core$load$fn__5448.invoke(core.clj:5866)
at clojure.core$load.doInvoke(core.clj:5865)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5671)
at clojure.core$load_lib$fn__5397.invoke(core.clj:5711)
at clojure.core$load_lib.doInvoke(core.clj:5710)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$load_libs.doInvoke(core.clj:5749)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$require.doInvoke(core.clj:5832)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at user$eval5.invoke(form-init2689406130111808873.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.eval(Compiler.java:6771)
at clojure.lang.Compiler.load(Compiler.java:7227)
at clojure.lang.Compiler.loadFile(Compiler.java:7165)
at clojure.main$load_script.invoke(main.clj:275)
at clojure.main$init_opt.invoke(main.clj:280)
at clojure.main$initialize.invoke(main.clj:308)
at clojure.main$null_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: clojure.lang.ArityException: Wrong number of args (-3) passed to: handler/dummy-mw
at clojure.lang.Compiler.macroexpand1(Compiler.java:6636)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6709)
... 46 more
Subprocess failed
However, if I substitute the :middlewares
metadata option for the middlewares
macro, everything works as expected. Here you can see the replacement:
(defapi app
(swagger-ui)
(swagger-docs
{:info {:title "Middlewares-issue"
:description "Compojure Api example"}
:tags [{:name "hello", :description "says hello in Finnish"}]})
(context* "/hello" []
:tags ["hello"]
:middlewares [(mw-with-args "dummy")]
(GET* "/" {:as request}
(ok (str (:dummy request) " " (:foo request))))))
Finally, I have to say that this error only appears when I use a middleware which requires additional arguments besides the handler. In other words, this doesn't throw:
(defapi app
(swagger-ui)
(swagger-docs
{:info {:title "Middlewares-issue"
:description "Compojure Api example"}
:tags [{:name "hello", :description "says hello in Finnish"}]})
(context* "/hello" []
:tags ["hello"]
:middlewares [mw-wo-args]
(GET* "/" {:as request}
(ok (str (:dummy request) " " (:foo request))))))