2

I have usual happstack case in which we have ServerPart Response MonadPlus in list and. Then msum Chooses the one that does not fail and response generated and returned.

I have opinion that some actions - like cheking cookies - preparing connection context (authorising authenticated user, implementing counts, etc...) should be done in any incoming request - without any path info even defined yet.

Maybe there's some buzzy word I still not knowing yet, specially for such kinds of staff. Could someone advice please?

Vasiliy Stavenko
  • 1,174
  • 1
  • 12
  • 29

1 Answers1

4

If you want to take certain actions for every request, you can add them in the do statement before your routing code. For example:

module Main where

import Happstack.Server

main = simpleHTTP nullConf $ do incCounter
                                mUser <- checkUserAuth
                                resp <- msum [ part1
                                             , part2
                                             , part3 mUser
                                             ]
                                logResponse resp
                                return resp

That will always run incCounter and checkUserAuth. Then it will try the various routes.

If one of the routes matches, it will then call logResponse, and then finally return the resp which will be sent to the user.

Note that while incCounter and checkUserAuth will always be run, logResponse will only be run if one of the parts matches. If none do, then I am pretty sure the code will escape and return a 404. If you wanted logResponse to always run, then you could add a handler to the msum that always matches. For example:

                 resp <- msum [ part1
                              , part2
                              , part3 mUser
                              , notFound $ toResponse "Sorry, page not found."
                              ]

That will almost always run. If one of the parts matches, but explicitly calls 'escape', then I am pretty sure logResponse still won't be run. There are ways of dealing with that as well.

But, the short answer is, if you want something to happen even time, just put it before your msum code.

stepcut
  • 1,502
  • 8
  • 10
  • I was confused by `readCookieValue` behaviour. It failed to read - due to cookie didn't existed yet, and the whole monad then assumed to be failed. I had to implement `checkUserAuth` in your example using `msum`. Thank you for answer - It was very useful. – Vasiliy Stavenko Dec 19 '12 at 09:09
  • It wasn't immediately obvious to me, so here is how you use `msum` to do what you describe: https://gist.github.com/xaviershay/fb1aa182e99fdb5cfe5e – Xavier Shay Sep 08 '13 at 23:47