2015-08-24 1 views
1

J'utilise un gabarit de luminus avec une configuration ring/compojure/swagger.ring.middleware.format_params.cjl lance sur JSON mal formé

Quand je nourris l'API REST i créé JSON malformé je reçois 500 et:

java.lang.IllegalArgumentException: No value supplied for key: {:formats (:json-kw :yaml-kw :edn :transit-json :transit-msgpack), :handle-error #<middleware$handle_req_error [email protected]>}, compiling:(pythonapi.clj:14:1) 
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3558) 
    at clojure.lang.Compiler$DefExpr.eval(Compiler.java:417) 
    at clojure.lang.Compiler.eval(Compiler.java:6708) 
    at clojure.lang.Compiler.load(Compiler.java:7130) 
    at clojure.lang.RT.loadResourceScript(RT.java:370) 
    at clojure.lang.RT.loadResourceScript(RT.java:361) 
    at clojure.lang.RT.load(RT.java:440) 
    at clojure.lang.RT.load(RT.java:411) 
    at clojure.core$load$fn__5066.invoke(core.clj:5641) 
    at clojure.core$load.doInvoke(core.clj:5640) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at clojure.core$load_one.invoke(core.clj:5446) 
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486) 
    at clojure.core$load_lib.doInvoke(core.clj:5485) 
    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
    at clojure.core$apply.invoke(core.clj:626) 
    at clojure.core$load_libs.doInvoke(core.clj:5524) 
    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
    at clojure.core$apply.invoke(core.clj:626) 
    at clojure.core$require.doInvoke(core.clj:5607) 
    at clojure.lang.RestFn.invoke(RestFn.java:1289) 
    at voicepin_collector.handler$eval23$loading__4958__auto____24.invoke(handler.clj:1) 
    at voicepin_collector.handler$eval23.invoke(handler.clj:1) 
    at clojure.lang.Compiler.eval(Compiler.java:6703) 
    at clojure.lang.Compiler.eval(Compiler.java:6692) 
    at clojure.lang.Compiler.load(Compiler.java:7130) 
    at clojure.lang.RT.loadResourceScript(RT.java:370) 
    at clojure.lang.RT.loadResourceScript(RT.java:361) 
    at clojure.lang.RT.load(RT.java:440) 
    at clojure.lang.RT.load(RT.java:411) 
    at clojure.core$load$fn__5066.invoke(core.clj:5641) 
    at clojure.core$load.doInvoke(core.clj:5640) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at clojure.core$load_one.invoke(core.clj:5446) 
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486) 
    at clojure.core$load_lib.doInvoke(core.clj:5485) 
    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
    at clojure.core$apply.invoke(core.clj:626) 
    at clojure.core$load_libs.doInvoke(core.clj:5524) 
    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
    at clojure.core$apply.invoke(core.clj:626) 
    at clojure.core$require.doInvoke(core.clj:5607) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at voicepin_collector.listener$_contextInitialized.invoke(listener.clj:1) 
    at voicepin_collector.listener.contextInitialized(Unknown Source) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1291) 
    at org.apache.catalina.manager.HTMLManagerServlet.start(HTMLManagerServlet.java:694) 
    at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:217) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:213) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:610) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IllegalArgumentException: No value supplied for key: {:formats (:json-kw :yaml-kw :edn :transit-json :transit-msgpack), :handle-error #<middleware$handle_req_error [email protected]>} 
    at clojure.lang.PersistentHashMap.create(PersistentHashMap.java:77) 
    at ring.middleware.format_params$wrap_restful_params.doInvoke(format_params.clj:251) 
    at clojure.lang.RestFn.invoke(RestFn.java:423) 
    at compojure.api.middleware$api_middleware.doInvoke(middleware.clj:214) 
    at clojure.lang.RestFn.invoke(RestFn.java:423) 
    at compojure.api.core$api_middleware_with_routes.invoke(core.clj:21) 
    at clojure.lang.AFn.applyToHelper(AFn.java:156) 
    at clojure.lang.AFn.applyTo(AFn.java:144) 
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3553) 
    ... 78 more 

Je crois que je dois intercepter cette exception afin d'informer l'utilisateur que malformé JSON a été écrit et retour 400.

Où est le meilleur endroit pour essayer/attraper?

Répondre

1

La façon habituelle dont je gère cela est de faire un nouveau middleware, en enveloppant le middleware existant, qui intercepte l'erreur attendue et renvoie votre message et votre statut personnalisés.

(defn safe-restful-params 
    [handler] 
    (fn [request] 
    (try ((wrap-restful-params handler) request) 
     (catch IllegalArgumentException e 
      {:status 400 ; bad request 
      :body "malformed JSON"})))) 

En pratique, vous voudrez probablement mettre des en-têtes, etc. et vous pouvez aussi écrire une version plus générale qui enveloppe middleware arbitraire au lieu de cuvelage spécial l'emballage de celui-ci, mais c'est le concept général. Un middleware en anneau prend toujours un gestionnaire comme argument, et renvoie une fonction que vous pouvez appeler sur une demande d'appel. Dans la pratique, il doit normalement appeler le gestionnaire de la requête dans le cadre de son exécution. Ce middleware insère également manuellement un autre middleware entre lui et le gestionnaire, et est destiné à remplacer cet autre middleware.

+0

PS. J'ai déterminé quel middleware lançait l'exception de la trace de la pile, n'hésitez pas à ajuster ce code si nécessaire si j'ai mal identifié le middleware qui conduit à cette exception. Peut-être que c'est en fait 'format-params'? – noisesmith