Я использую servant
для простого JSON API, который позволяет создавать пользователей, чьи имена должны быть уникальными.Это обеспечивается уникальным ограничением в SQLite.У меня есть функция DB.saveUser :: UserReq -> IO Int
, которая (что неудивительно) сохраняет пользователей в SQLite и возвращает сгенерированный идентификатор.Он выдаст SQLError ErrorConstraint _ _
, если имя уже занято.Я хочу вернуть HTTP-код ответа 409, если это произойдет.Поэтому мой вопрос был бы: есть ли способ поймать SQLError
в монаде обработчика?Если нет, то какой самый чистый способ достичь того, что я ищу?Я думал о том, чтобы заставить DB.saveUser
вернуть Maybe Int
, но почему-то я думаю, что должно быть лучшее решение.
createUser :: UserReq -> Handler (Headers '[Header "Location" Text] NoContent)
createUser ur = do id <- liftIO (DB.saveUser ur)
return . addHeader (T.pack ("/user/" ++ show id)) $ NoContent
saveUser (UR.UserReq name) = withConnection database $ \conn ->
do executeNamed conn "INSERT INTO users (name) VALUES (:name)" [":name" := name]
fromIntegral <$> lastInsertRowId conn