2015-10-13 70 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添加了一些关于这一点。 –