This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-02-23
Channels
- # aws-lambda (1)
- # beginners (11)
- # boot (456)
- # cider (3)
- # cljsrn (7)
- # clojure (340)
- # clojure-berlin (6)
- # clojure-dev (207)
- # clojure-germany (12)
- # clojure-greece (3)
- # clojure-italy (3)
- # clojure-russia (12)
- # clojure-spec (42)
- # clojure-uk (29)
- # clojured (7)
- # clojurescript (125)
- # datascript (1)
- # datomic (47)
- # defnpodcast (4)
- # emacs (30)
- # events (7)
- # hoplon (13)
- # instaparse (64)
- # jobs (13)
- # jobs-discuss (1)
- # lein-figwheel (1)
- # leiningen (10)
- # luminus (1)
- # lumo (14)
- # off-topic (10)
- # om (16)
- # om-next (3)
- # onyx (1)
- # pedestal (3)
- # protorepl (5)
- # re-frame (17)
- # reagent (66)
- # ring (1)
- # ring-swagger (13)
- # spacemacs (12)
- # specter (4)
- # untangled (272)
- # vim (4)
- # yada (24)
This is probably all due to a misunderstanding on my part. I have a resource:
(yada/resource
(merge
{:id :deps.jars/index
:produces "text/html"
:methods {:get {:response (fn [ctx]
(dasync/chan->defferred
(go
(let [characters (async/<! (db/all-characters db/db))]
(tmpl/app-template ctx
[:section.container [:h3 "Recent deploys"]]
[:section.container
[:h3 "Characters"]
(for [c characters]
[:p "Character: " (:name c) " specialty " (:specialty c)])])))))}}
}
access-control))
If an exception is thrown here, Yada returns a 404, not a 500 as I would expect. I can see there are ways to explicitly set status codes, but I would assume that a 500 is more appropriate for a thrown exception?Hmm, doing more testing, if I throw a non-async exception I get a 500
Hmm. Are you possibly returning nil? That triggers a 404, it's somewhat of a yada pun.
yeah I think that's the problem
the go block is throwing, and it's being converted to a deferred, so the go block returns nil
I was confused by the stack because I could see
and I assumed that there was an exception being caught in there
reading more closely I can see it's just a normal yada 404
I think I'm probably going to narrowly tailor my core.async use and try to use manifold more.
i find manifold/Deferred's built-in error states make it a lot more convenient than core.async
you mean 'cos you can't use the error-state of the deferred returned by stream/take!
@stijn ?
(or at least, if you can i couldn't figure out how to)
yeah, i ended up doing the core.async thing and putting an exception on a stream as a value, which is kinda sucky
well at least with core.async you can have a generic error handler do that, with transform, you have to wrap all your map / filter steps in error handling code
For those following along at home, here's what I came up with:
{:response (fn [ctx]
(d/let-flow [characters (dasync/chan->defferred (db/all-characters db/db))]
(tmpl/app-template ctx
[:section.container [:h3 "Recent deploys"]]
[:section.container
[:h3 "Characters"]
(for [c characters]
[:p "Character: " (:name c) " specialty " (:specialty c)])])))}
(defn throw-err [e]
(when (instance? Throwable e) (throw e))
e)
(defn chan->defferred
"Converts a core.async channel (containing one value) into a deferred."
[ch]
(d/chain (stream/take!
(stream/->source ch))
throw-err))
you could also use core.async/take!
to call deferred/success!
I think I follow, would that also work for exceptions?
Thanks, is this correct?
(defn chan->deferred2
"Converts a core.async channel (containing one value) into a deferred."
[ch]
(let [d (d/deferred)]
(async/take! ch
(fn [v]
(if (instance? Throwable v)
(d/error! d v)
(d/success! d v))))
d))
looks about right to me
Awesome, thanks 🙂