2015-10-13 103 views
2

當我查詢my database時,可能會拋出one of four different kinds of exceptions捕捉多種類型的異常

FormatError 
QueryError 
ResultError 
SqlError 

我想要寫映入任何由query產生的那些4點的異常,並將它們升降機成ExceptT的功能。

runQuery :: (ToRow q, FromRow r) => Query -> q -> ExceptT ServantErr IO [r] 
runQuery conn q sub = do 
    res <- liftIO $ try $ Postgres.query conn q sub 
    case res of 
     Left err -> throwError (postgresErr err) 
     Right r -> return r 

postgresErr :: ??? -> ServantErr 
postgresErr e = err500 { errBody = ByteString.pack (show e) } 

這不起作用。 try沒有捕捉任何東西。我如何捕獲4種異常類型中的任何一種,並根據類型將其映射到ServantErr,但仍允許我不處理的任何異常通過?

回答

6

GHC的Exception class forms a hierarchy,其中SomeException類型在頂部。因此,爲了捕捉任何毫無例外,使用:(理想情況下postgresql-simple可以添加自己的中間捕獲所有異常的,你可以使用的類型,但我看不到任何)

postgresErr :: SomeException -> ServantErr 

如果你想趕上正是這四個,我知道最好的辦法是使用catches功能:

catches :: IO a -> [Handler a] -> IO a 

不幸的是這需要你爲每一個Handler (儘管他們可能只會在類型簽名上有所不同)。

+0

如果我只想抓住他們,如果他們是這四種類型之一呢? –

+0

@SeanClarkHess添加了一些關於這一點。 –