2

我的中间件仅针对异步请求引发错误,不知道为什么:

项目.clj

 (defproject asyncy "0.1.0-SNAPSHOT"
   :description "FIXME: write description"
   :dependencies [[org.clojure/clojure "1.9.0"]
                  [metosin/compojure-api "1.1.11"]
                  [org.clojure/core.async "0.3.442"]]
   :ring {:handler asyncy.handler/app}
   :uberjar-name "server.jar"
   :profiles {:dev {:dependencies [[javax.servlet/javax.servlet-api "3.1.0"]]
                   :plugins [[lein-ring "0.12.0"]]}})

处理程序.clj

为了让讨论和诊断更容易,我使用了这个问题的最低限度版本lein new compojure-api template

(ns asyncy.handler
  (:require [compojure.api.sweet :refer :all]
            [ring.util.http-response :refer :all]
            [schema.core :as s]
            [clojure.core.async :as async]))

(s/defschema Pizza
  {:name                         s/Str
   (s/optional-key :description) s/Str
   :size                         (s/enum :L :M :S)
   :origin                       {:country (s/enum :FI :PO)
                                  :city    s/Str}})

(def app
  (api
    {:async?     true
     :swagger
                 {:ui   "/"
                  :spec "/swagger.json"
                  :data {:info {:title       "Asyncy"
                                :description "Compojure Api example"}
                         :tags [{:name "api", :description "some apis"}]}}}

    (context "/api" []
      :tags ["api"]
      :middleware [(fn [handler]
                     ;; this sync-style handler always handles both sync and async requests
                     (fn ([request]
                          (clojure.pprint/pprint request)
                          (if (some-> request :params :x (= "1"))
                            (bad-request {:error true :message "one is the loneliest number that you'll ever do"})
                            ;; this throws an error on async requests
                            (handler request)))

                       ;; this async 3-arity handler is never called
                       ([request b c]
                        (clojure.pprint/pprint ["never called, doesnt matter." request b c]))
                       ))]

      (GET "/plus" []
        :return {:result Long}
        :query-params [x :- Long, y :- Long]
        :summary "adds two numbers together"
        (ok {:result (+ x y)}))

      (GET "/plus-async" []
        :return {:result Long}
        :query-params [x :- Long, y :- Long]
        :summary "adds two numbers together"
        (fn [request respond raise]
          (respond (ok {:result (+ x y)}))))
      )))

(handler request)中间件是引发错误的原因,仅适用于异步请求:

ERROR Wrong number of args (1) passed to: handler/fn--26289/fn--26301/fn--26303
clojure.lang.ArityException: Wrong number of args (1) passed to: handler/fn--26289/fn--26301/fn--26303
        at clojure.lang.AFn.throwArity(AFn.java:429)
        at clojure.lang.AFn.invoke(AFn.java:32)
        at compojure.response$eval1960$fn__1961.invoke(response.clj:47)
        at compojure.response$eval1882$fn__1883$G__1873__1890.invoke(response.clj:7)
        at compojure.core$wrap_response$fn__3839.invoke(core.clj:158)
        at compojure.core$pre_init$fn__3938.invoke(core.clj:328)
        at compojure.api.coerce$body_coercer_middleware$fn__14642.invoke(coerce.clj:51)
        at compojure.core$pre_init$fn__3940$fn__3943.invoke(core.clj:335)
        at compojure.core$wrap_route_middleware$fn__3823.invoke(core.clj:127)
        at compojure.core$wrap_route_info$fn__3828.invoke(core.clj:137)
        at compojure.core$wrap_route_matches$fn__3832.invoke(core.clj:146)
        at compojure.core$wrap_routes$fn__3950.invoke(core.clj:348)
        at compojure.api.routes.Route.invoke(routes.clj:74)
        at compojure.core$routing$fn__3847.invoke(core.clj:185)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at compojure.core$routing.invokeStatic(core.clj:185)
        at compojure.core$routing.doInvoke(core.clj:182)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invokeStatic(core.clj:659)
        at clojure.core$apply.invoke(core.clj:652)
        at compojure.core$routes$fn__3851.invoke(core.clj:192)
        at asyncy.handler$fn__26289$fn__26290$fn__26291.invoke(handler.clj:32)
        at compojure.core$routing$fn__3847.invoke(core.clj:185)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at compojure.core$routing.invokeStatic(core.clj:185)
        at compojure.core$routing.doInvoke(core.clj:182)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invokeStatic(core.clj:659)
        at clojure.core$apply.invoke(core.clj:652)
        at compojure.core$routes$fn__3851.invoke(core.clj:192)
        at compojure.core$make_context$handler__3919.invoke(core.clj:285)
        at compojure.core$make_context$fn__3921.invoke(core.clj:293)
        at compojure.api.routes.Route.invoke(routes.clj:74)
        at compojure.api.core$handle$fn__14853.invoke(core.clj:8)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at compojure.api.core$handle.invokeStatic(core.clj:8)
        at compojure.api.core$handle.invoke(core.clj:7)
        at clojure.core$partial$fn__5561.invoke(core.clj:2616)
        at compojure.api.routes.Route.invoke(routes.clj:74)
        at ring.swagger.middleware$wrap_swagger_data$fn__14015.invoke(middleware.clj:35)
        at ring.middleware.http_response$wrap_http_response$fn__8034.invoke(http_response.clj:19)
        at ring.swagger.middleware$wrap_swagger_data$fn__14015.invoke(middleware.clj:35)
        at compojure.api.middleware$wrap_options$fn__14077.invoke(middleware.clj:74)
        at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
        at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
        at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
        at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
        at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
        at compojure.api.middleware$wrap_exceptions$fn__14067.invoke(middleware.clj:43)
        at ring.middleware.format_response$wrap_format_response$fn__7930.invoke(format_response.clj:194)
        at ring.middleware.keyword_params$wrap_keyword_params$fn__8076.invoke(keyword_params.clj:36)
        at ring.middleware.nested_params$wrap_nested_params$fn__8134.invoke(nested_params.clj:89)
        at ring.middleware.params$wrap_params$fn__4079.invoke(params.clj:67)
        at compojure.api.middleware$wrap_options$fn__14077.invoke(middleware.clj:74)
        at compojure.api.routes.Route.invoke(routes.clj:74)
        at clojure.lang.Var.invoke(Var.java:381)
        at ring.middleware.reload$wrap_reload$fn__1829.invoke(reload.clj:39)
        at ring.middleware.stacktrace$wrap_stacktrace_log$fn__1211.invoke(stacktrace.clj:26)
        at ring.middleware.stacktrace$wrap_stacktrace_web$fn__1277.invoke(stacktrace.clj:96)
        at ring.adapter.jetty$proxy_handler$fn__487.invoke(jetty.clj:25)
        at ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:499)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
        at java.lang.Thread.run(Thread.java:748)

如何使用 async compojure-api 做中间件?感觉就像我完全不知道如何实现这一点。

4

0 回答 0