Skip to content

Compilation error on context* middleware metadata when middleware require args  #190

Closed
@rcanepa

Description

@rcanepa

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))))))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions