1. new in this version
  2. build a web 2.0 app in happstack
  3. why happstack is cool
  4. getting started with happstack
  5. prerequisites
  6. cabal install me
  7. first shot at happstack
  8. url handling
  9. basic HTML inclusion
  10. templates
  11. stringtemplate basics
  12. debugging
  13. form data: get and post
  14. form data: file uploads
  15. cookies
  16. introduction to macid
  17. first steps with macid
  18. scaling with multimaster
  19. using macid safely
  20. macid dummy data
  21. changing the data model
  22. macid stress test
  23. limitations of macid
  24. foreign characters
  25. IxSets
  26. cron jobs
  27. thanks
  28. appendix (floundering in ghci)

Debugging

A few words on debugging.

One thing you can do is put debugFilter before the serverPartT that seems to be causing trouble. This will spit out the request and response objects, which can be helpful.

*Main> :i debugFilter
debugFilter ::
(Show a, Control.Monad.Trans.MonadIO m) =>
ServerPartT m a -> ServerPartT m a
-- Defined in Happstack.Server.SimpleHTTP

I personally don't use debugFilter much, as it gives almost too much information.

Instead, I depend on Debug.Trace.trace (a standard library function which sneaks IO in anywhere you have a showable value), which I augmented with some helper functions (in Misc.hs).

traceTrue x = trace (show x ++ "nn") True
traceIt x = trace (show x ++ "nn") x
traceMsg msg x = trace ( "nn" ++ msg ++ (show x) ++ "nn") x

Typical (basically only) use of traceTrue: view arguments to a function in stdout, by putting it on the right side of the "execute this branch if true" bar in a function definition. The function executes as it normally would, because traceTrue always returns true, but you get debugging info as a side effect.

tutlayout (RenderGlobals ts mbU) attrs tmpl0 | traceTrue ((RenderGlobals ts mbU), attrs, tmpl0) = .....

Typical use of traceIt: quickie print to stdout of some var or expression:

mainUserMenu = if (isJust mbU)
  then traceIt $ paintHMenu .
   map (menuLink ts ("/tutorial/" ++ tmpl0) )
    . readtut $ "mainusermenu"
  else ""

traceMsg does pretty much the same thing as traceIt, except you preface the shown expression with your own message like "show the menu: ". This can be useful if you are doing more than one trace and need to distinguish them.

There are probably smarter ways of debugging a happs app; the above is just what works for me. (Actually, I debug using these trace helpers all the time, not just in Happstack.) If I get useful feedback on how other Happstack users approach debugging I will update this page.

Incidentally, ghci has a debugger since 6.8.3. Overall it's great, but I didn't find it too useful for Happstack, because it would die out on me in ways I didn't understand, typically around hard to understand exceptions. Basically, Happstack would behave differently when I was stepping through it with the ghci debugger than it would when running without the debugger. I suspect it's because the ghci debugger lacks support for multithreaded programs, or something along those lines. At any rate, I wound up not using the interactive debugger much, though I would have liked to.

Now, on to the pragmatic matter of form data.