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
Теперь мне нужно выяснить, как правильно перехватить это исключение и вернуть правильное сообщение об ошибке.
Спасибо!
1 ответ
Возврате Nothing
это не то же самое, что неудача. Вам нужно будет выдать исключение времени выполнения (через что-то вроде throwIO
) для упорных трактовать это как ситуацию отката.