After I added :as-response to add in the headers to name the downloaded file, I'm getting an java.lang.Exception Unrecognized body: {:invalid-results {:extra-params #{"formdat"}, :missing-params #{"format"}}
when I have invalid parameters in my URL.
I'm thinking now :malformed? and :handle-malformed are not the correct place to do the checks I'm doing, but let's see..
I have a :malformed? function which returns a Vector indicating the Liberator if the URL is malformed or not. i.e. [true {:my-invalid-results {:error1 "some-error} :representation {media-type "application/json"} ]
true tells Liberator that the URL is malformed and to therefore call the :handle-malformed function.
In handle-malformed I was simply pulling out some-data from the map and returning it. (ctx-map :my-invalid-results) This worked until I added :as-response
Worked meaning the map was formatted and shown in the browser as a table, to indicate to the caller was is wrong when calling the restful service.
After adding the :as-response function, I see the return value of handle-malformed is (the map) is passed as the first param (i.e. body) to this function yielding the Exception noted above. It seems it's expecting a String as the body.
Here's a boiled down negative case example:
(defresource testit
:available-media-types ["text/plain"]
:malformed? (fn [ctx]
[true ; true = the request is malformed
{:invalid-results {:extra-params #{"formdat"}, :missing-params #{"format"}} :representation {:media-type "text/html"}}])
:handle-malformed (fn [ctx]
(println "In handle-malformed = " (ctx :invalid-results))
(ctx :invalid-results))
:handle-ok (fn [ctx] "some,csv,data")
:as-response (fn [resp-body ctx]
(println "In as-response = " resp-body)
(let [media-type "csv"] ; declare media-type for demo purposes only
(if (= media-type "csv")
(-> {:body resp-body}
(assoc-in [:headers "Content-Disposition"] "attachment; filename=data.csv"))
{:body resp-body}))))
With :as-response I get...
In handle-malformed = {:extra-params #{formdat}, :missing-params #{format}}
In as-response = {:extra-params #{formdat}, :missing-params #{format}}
2015-02-23 17:38:12 WARN AbstractHttpConnection:521 - /testit
java.lang.Exception: Unrecognized body: {:extra-params #{"formdat"}, :missing-params #{"format"}}
at ring.util.servlet$set_body.invoke(servlet.clj:103)
at ring.util.servlet$update_servlet_response.invoke(servlet.clj:113)
at ring.adapter.jetty$proxy_handler$fn__97.invoke(jetty.clj:22)
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:116)
at org.eclipse.jetty.server.Server.handle(Server.java:369)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:486)
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:933)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:995)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:745)
If I comment the :as-response out, I see the map nicely formatted as html.. in the browser.
extra-params | #{"formdat"} |
---|
missing-params | #{"format"} |
---|
How can I add in the filename in as-response when needed and to have error checking and pass back what is wrong with the url (currently in map form, but married to it)?
Thanks,
Steve