New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Offer HandlerM built on Aff (Asynchronous Eff) #15
Comments
Haven't heard of Aff, but it's definitely better than |
👍, I was just trying to use purescript-express with redis, and the node redis library is entirely asynchronous (and my wrapper for it is built on Aff), so I have no way to write a handler that can respond based on my interaction with redis. 😢 edit: I ended up doing something like this for now: liftCallback :: forall a eff. ((a -> Eff eff Unit) -> Eff eff Unit) -> (a -> HandlerM Unit) -> HandlerM Unit
liftCallback f next = do
cb <- capture next
liftEff (f cb)
foreign import insert :: forall eff. String -> String -> Database -> (Boolean -> DBEff eff Unit) -> DBEff eff Unit
... do
...
liftCallback (insert key value db) $ \success ->
... but Aff support would be so much better. |
* Changes HandlerM to use Aff (asynchronous effects) instead of Eff * Adds a type parameter (`e`) for the effect rows to HandlerM to get rid of `unsafeInterleaveEff`. Normally when writing top-level handlers one can write: myHandler :: forall e. Handler e which is a type alias for myHandler :: forall e. HandlerM (express :: EXPRESS | e) Unit * Removes `capture` as it's no longer needed. Async code can be wrapped with Aff and `Aff` can be lifted to `HandlerM` with `liftAff`.
* Changes HandlerM to use Aff (asynchronous effects) instead of Eff * Adds a type parameter (`e`) for the effect rows to HandlerM to get rid of `unsafeInterleaveEff`. Normally when writing top-level handlers one can write: myHandler :: forall e. Handler e which is a type alias for myHandler :: forall e. HandlerM (express :: EXPRESS | e) Unit * Removes `capture` as it's no longer needed. Async code can be wrapped with Aff and `Aff` can be lifted to `HandlerM` with `liftAff`.
* Changes HandlerM to use Aff (asynchronous effects) instead of Eff * Adds a type parameter (`e`) for the effect rows to HandlerM to get rid of `unsafeInterleaveEff`. Normally when writing top-level handlers one can write: myHandler :: forall e. Handler e which is a type alias for myHandler :: forall e. HandlerM (express :: EXPRESS | e) Unit * Removes `capture` as it's no longer needed. Async code can be wrapped with Aff and `Aff` can be lifted to `HandlerM` with `liftAff`.
How should I handle errors in Aff? I have a code like this: upstreamAuth (AppStateRecord state) token = do
let opts = state.upstream
<> method := "POST"
<> path := "/_session"
reqdata <- liftEff $ Buffer.fromString token UTF8
res <- SR.simpleRequest opts reqdata
pure res.body
checkAuth::forall e. AppState -> Token -> Aff (ref::REF, http::HTTP|e) Cookie
checkAuth stateref token = do
state <- liftEff $ readRef stateref
case getSession token state of
Nothing -> upstreamAuth state token
Just session -> pure session.cookie
authHandler :: forall e. AppState -> Handler (console::CONSOLE, http::HTTP, ref::REF | e)
authHandler statedata = do
token <- getRequestHeader "Authorization"
case token of
Nothing -> nextThrow $ error "NOAUTH"
Just user -> case parseUser user of
"" -> nextThrow $ error "NOAUTH"
u -> do
liftEff $ log ("API token: " <> u)
cookie <- liftAff $ checkAuth statedata u
liftEff $ log ("Cookie: " <> cookie)
next And the errors which happen in |
@kika you can use |
@Risto-Stevcev right, that's what I've started with, but then it introduces another |
It would be really cool if HandlerM were a transformer on Aff (https://github.com/slamdata/purescript-aff), or to offer AsyncHandlerM so we could more easily write Handlers with lots of callbacks:
Doing something like this with
capture
can get ugly.The text was updated successfully, but these errors were encountered: