Please update the title to indicate that this was written in 2009. In the meanwhile, Haskell has gained (besides Happstack) two excellent web frameworks: Snap and Yesod.
One of the points of critique has been addressed now is database access. For instance, Persistent provides type-safe database access:
http://www.yesodweb.com/book/persistent
The author also mentions the problem that exceptions can only be caught in the IO monad. But this has become less of a problem, since more people started using monad transformers (such as ErrorT) to add error handling to their monads. ErrorT allows you to catch exceptions within that monad. For instance, quoting from one of my own projects:
readEntry :: MonadIO m => Corpus -> String -> ErrorT CorpusError m Text
readEntry is a function that takes a Corpus and a String, and returns Text in a monad of the class MonadIO if the function is successful. Otherwise it reports errors in the form of a CorpusError. You could now, for instance, run this function with runErrorT, and it will return an ordinary Either value in the given monad (Left CorpusError in the case of an error, Right Text when the call is successful).