Fork me on GitHub
#pedestal
<
2018-04-06
>
mtnygard13:04:53

@pithyless Thank you, this is excellent. I will look into it later today.

dadair16:04:10

@pithyless I could be wrong, but don’t you just want to return the channel returned from the go? not provide an explicit extra channel?

dadair16:04:03

e.g.,

(def do-work-async
  {:name :do-work-async
   :enter (fn [ctx]
            (let [ch (async/chan)]
              (async/go
                (async/>! ch
                          (if (:async-error ctx)
                            (assert nil "Async error")
                            (assoc ctx :async :ok))))
              ch))})
should be
(def do-work-async
  {:name :do-work-async
   :enter (fn [ctx]
            (async/go
                (if (:async-error ctx)
                    (assert nil "Async error")
                    (assoc ctx :async :ok))))})
I haven’t tested and edited the code in slack so parens are probably wrong

dadair16:04:36

(def third-party-auth
  {:name ::third-party-auth
   :enter (fn [context]
            (if (:session context)
              context
              (go
                (assoc context :auth-response (call-auth-system context))))})
they implicitly return a channel because the (go ..) returns a channel

pithyless16:04:23

@dadair in this case, having the async/go return would be sufficient; but it makes no difference - error is the same

mtnygard16:04:30

@pithyless There could be another difference. The assert is going to throw an exception that will be silently swallowed by the inner go. Nothing at all is going to come out of the channel if that happens.

mtnygard16:04:48

But now that I look at it... I'm not sure how the assert would get caught outside any go block. I will have to take a fresh look at the Pedestal source to understand.

pithyless16:04:13

@mtnygard @dadair so without the explicit channel, just returning an implicit async/go channel, we see something like this:

pithyless16:04:53

Async error...
Exception in thread "async-dispatch-5" java.lang.AssertionError: Assert failed: Async error
nil
[OK] Handling error.
clojure.lang.ExceptionInfo: Async Interceptor closed Context Channel before delivering a Context
 at clojure.core$ex_info.invokeStatic (core.clj:4739)
    clojure.core$ex_info.invoke (core.clj:4739)

mtnygard16:04:20

I was just looking at the line of source that throws that exception. 🙂

mtnygard16:04:21

If you want the exception to be processed with Pedestal's error handling, I guess you need to catch Throwable and attach it to the context map before putting the context map into the channel.

mtnygard16:04:30

I don't think we have that documented very well. 😞

mtnygard16:04:00

Yes, but without the extra channel.

pithyless16:04:19

right, fair enough

pithyless16:04:06

so yeah… that’s not obvious from the documentation as it’s written now :]

mtnygard16:04:15

This part really doesn't behave the way I'd expect it to. And the docs are definitely misleading.

mtnygard16:04:22

Sorry you had to struggle with this.

mtnygard16:04:32

We'll try to make it better.

pithyless16:04:01

no problem; I just assumed I was doing something wrong 🙂

mtnygard16:04:22

I've got to run. Feel free to send me a DM if you run into more trouble.

pithyless16:04:33

@mtnygard thanks for your help! interceptor.chain/execute is still a really nice way to decomplect a workflow 🙂