MaybeT e transações no runDb

Para minha pergunta anterior sobre falhas de encadeamento, Michael Snoyman sugeriu que eu usasseMaybeT executá-los, se algum deles falhar, ele apenas entrará em curto-circuito paraNothing.

Estava com a impressãorunDb executa tudo em uma transação. Portanto, uma falha em qualquer ponto do código não reverterá automaticamente a transação?

mauth <- runDb $ runMaybeT $ do
            valid    <- MaybeT $ return $ listToMaybe errs 
            uid      <- MaybeT $ insertUnique u 
            vid     <- MaybeT $ getBy $ UniqueField v -- this step fails but previous insert does not roll back
            auth     <- liftIO $ createAuthToken uid
            return auth

Quando executo o código acima, ogetBy falha, mas o usuário ainda foi inserido. Estou entendendo mal querunDb reverterá em umNothing dentroMaybeT? Preciso usar outra Mônada para que isso funcione?

Aprecie seus pensamentos sobre a melhor forma de reverter a falha.

Atualizar: Foi o que acabei fazendo por sugestão de Michael.

mauth <- runDb $ do
          ma <- runMaybeT $ do
                   valid <- ... 
          case ma of
            Just _ -> return ma
            Nothing -> liftIO $ throwIO MyException

Agora, preciso descobrir como capturar essa exceção muito bem do lado de fora e retornar uma mensagem de erro adequada.

Obrigado!

questionAnswers(1)

yourAnswerToTheQuestion