MaybeT и транзакции в runDb
На мой предыдущий вопрос о сбоях цепочки Майкл Снойман предложил мне использоватьMaybeT
чтобы запустить их так, если какой-либо из них потерпит неудачу, он просто замкнетNothing
.
Я был под впечатлениемrunDb
запускает все в транзакции. Так не должен ли сбой в любой точке кода автоматически откатить транзакцию?
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
Когда я запускаю приведенный выше код,getBy
не удалось, но пользователь все еще был вставлен. Я неправильно понимаю, чтоrunDb
будет откат наNothing
внутриMaybeT
? Нужно ли использовать какую-то другую монаду, чтобы это работало?
Цените ваши мысли о том, как лучше всего откатиться на неудачу.
ОбновитьЭто то, что я сделал в соответствии с предложением Майкла.
mauth <- runDb $ do
ma <- runMaybeT $ do
valid <- ...
case ma of
Just _ -> return ma
Nothing -> liftIO $ throwIO MyException
Теперь мне нужно выяснить, как красиво перехватить это исключение и вернуть правильное сообщение об ошибке.
Спасибо!