Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Haskell MongoDB驱动程序检索错误状态_Mongodb_Haskell_Error Handling - Fatal编程技术网

从Haskell MongoDB驱动程序检索错误状态

从Haskell MongoDB驱动程序检索错误状态,mongodb,haskell,error-handling,Mongodb,Haskell,Error Handling,我有一个MongoDB,其中有一个集合用户,其中包含电子邮件上的唯一索引: import Data.Bson (Value (Int32)) import Database.MongoDB (Index (..), createIndex, (=:)) createIndex $ Index "user" [ "email" =: Int32 1 ] "email" True False 我编写了一个函数,如果电子邮件地址未被使用,则插入新用户,如果电子邮件地址已被占用,则应失

我有一个MongoDB,其中有一个集合
用户
,其中包含
电子邮件
上的唯一索引:

import Data.Bson        (Value (Int32))
import Database.MongoDB (Index (..), createIndex, (=:))

createIndex $ Index "user" [ "email" =: Int32 1 ] "email" True False
我编写了一个函数,如果电子邮件地址未被使用,则插入新用户,如果电子邮件地址已被占用,则应失败:

import           Data.Bson        (Value (ObjId))
import           Database.MongoDB (Action, ObjectId, (=:))
import qualified Database.MongoDB as M (insert)

data User = User
  { email     :: Text
  , firstName :: Text
  , lastName  :: Text
  } deriving Show

data MongoEntity a = MongoEntity ObjectId a

createIfNotExists :: User
                  -> Action Handler (Either Text (MongoEntity User))
createIfNotExists (user@User {..}) = do
  value <- M.insert "user" [ "email" =: email
                           , "firstName" =: firstName
                           , "lastName" =: lastName
                           ]
  case value of
    ObjId objectId -> return (Right $ MongoEntity objectId user)
    _ -> return $ Left "no document"

值之后,我从未使用过此模块,但阅读文档后,我能想到的最好方法是:

更改
createIfNotExists

createIfNotExists :: MonadIO m =>
                     User -> Action m (Either String (MongoEntity User))
使用
Control.Exception.Base
中的
catchJust
。作者似乎不鼓励使用
Control.Monad.Error.Class

main :: IO ()
main = do
  pipe <- connect (host "127.0.0.1")
  let user = User "jd@bar.baz" "John" "Doe"
  eitherEntity <- catchJust writeFailureErrorStr
                  (access pipe master "user" $ createIfNotExists user)
                  (return . Left)
  close pipe

writeFailureErrorStr  :: Failure -> Maybe String
writeFailureErrorStr (WriteFailure _err str) = Just str
writeFailureErrorStr _other = Nothing
main::IO()
main=do

pipe根据Jean-Baptiste Potonnier的回答,在阅读了Michael Snoyman(和)的两篇文章后,我将代码改写如下:

import           Control.Exception.Lifted (handleJust)
import           Data.Bson                (Value (ObjId))
import qualified Data.Bson                as B (Value)
import qualified Data.Text                as T (pack)
import           Database.MongoDB         (Action, Failure (..), (=:))
import qualified Database.MongoDB         as M (insert)

createIfNotExists :: User -> Action Handler (Either Failure (MongoEntity User))
createIfNotExists user =
  handleJust writeFailureHandler (return . Left) $ do
    value <- insertUser user
    return $
      case value of
        ObjId objectId -> Right $ MongoEntity (T.pack $ show objectId) user
        _ -> error "Unexpected missing document"

  where
    writeFailureHandler :: Failure -> Maybe Failure
    writeFailureHandler writeFailure@WriteFailure{} = Just writeFailure
    writeFailureHandler _ = Nothing

insertUser :: User -> Action Handler B.Value
insertUser User{..} =
  M.insert "users" [ "email" =: email
                   , "firstName" =: firstName
                   , "lastName" =: lastName
                   ]
import Control.Exception.Lifted(handleJust)
导入数据.Bson(值(ObjId))
导入符合条件的数据。Bson为B(值)
导入符合条件的数据。文本为T(打包)
导入Database.MongoDB(操作、失败(..),(=:)
将符合条件的Database.MongoDB作为M导入(插入)
createIfNotExists::用户->操作处理程序(失败(MongoEntity用户))
createIfNotExists用户=
handleJust writeFailureHandler(return.Left)$do
value Right$MongoEntity(T.pack$show objectId)用户
_->错误“意外丢失文档”
哪里
writeFailureHandler::失败->可能失败
writeFailureHandlerwriteFailure@WriteFailure{}=刚刚写入文件
writeFailureHandler=无
insertUser::User->Action Handler B.值
插入器用户{..}=
M.插入“用户”[“电子邮件”=:电子邮件
,“firstName”=:firstName
,“lastName”=:lastName
]

使用该软件包。

谢谢。我进一步阅读了库源代码,并倾向于捕捉异常。由于MongoDB不支持事务,使用find后跟insert会打开一个可能的争用条件。顺便说一句,以下是MongoDB错误代码列表:
import           Control.Exception.Lifted (handleJust)
import           Data.Bson                (Value (ObjId))
import qualified Data.Bson                as B (Value)
import qualified Data.Text                as T (pack)
import           Database.MongoDB         (Action, Failure (..), (=:))
import qualified Database.MongoDB         as M (insert)

createIfNotExists :: User -> Action Handler (Either Failure (MongoEntity User))
createIfNotExists user =
  handleJust writeFailureHandler (return . Left) $ do
    value <- insertUser user
    return $
      case value of
        ObjId objectId -> Right $ MongoEntity (T.pack $ show objectId) user
        _ -> error "Unexpected missing document"

  where
    writeFailureHandler :: Failure -> Maybe Failure
    writeFailureHandler writeFailure@WriteFailure{} = Just writeFailure
    writeFailureHandler _ = Nothing

insertUser :: User -> Action Handler B.Value
insertUser User{..} =
  M.insert "users" [ "email" =: email
                   , "firstName" =: firstName
                   , "lastName" =: lastName
                   ]