2014-01-27 64 views
6

我使用hedis并试图处理服务器死机的情况。根据文档:例外情况未被'尝试'捕获

连接到服务器丢失: 在连接丢失的情况下,命令函数会抛出ConnectionLostException。它只能在runRedis之外被捕获。

所以我会假设我想赶上ConnectionLostException。然而,虽然我似乎能够正确地看到它,但它似乎也会泡到顶端,我不知道为什么。下面是一些代码(只是GHCI运行):

:set -XOverloadedStrings 
import Database.Redis 
import Control.Exception 

conn <- connect defaultConnectInfo 
runRedis conn $ ping 

现在,如果我杀了进行连接和运行命令之间Redis的服务器,我得到的结果,我希望:

&langle;互动&rangle ;:ConnectionLost ***例外:ConnectionLost

所以不是我尝试做如下(我为了增加>>= evaluate试图迫使错误的评估,但它并没有区别):

let tryR = try :: IO a -> IO (Either ConnectionLostException a) 
tryR . (>>= evaluate) . runRedis conn $ ping 

这给了我:

左缺点:ConnectionLost nectionLost

所以我得到Left结果作为预期,但中途异常也可能被抓并由GHCI显示。这是没有被评估的事情吗?

+3

我不明白。一切似乎对我来说都是正确的:您已将异常转换为易于检查的“Either”值。你预计会发生什么? –

+1

它看起来像redis包是打印一个关于丢失的连接的字符串,除了抛出异常。 –

+0

@DanielWagner我正在转换异常,但仍然(据我所知)看到它由GHCI处理,就好像它仍然被抛出一样。除非JohnL说,并且redis本身正在打印该信息。 – Impredicative

回答

1

像约翰暗示的那样,似乎有些东西会将此消息打印到stderr

考虑这个例子:

{-# LANGUAGE OverloadedStrings #-} 

import Control.Concurrent (threadDelay) 
import Control.Exception 
import Control.Monad 
import Database.Redis 
import System.Mem 

tryR :: IO a -> IO (Either ConnectionLostException a) 
tryR = try 


main :: IO() 
main = do 
    conn <- connect defaultConnectInfo 
    loop conn 
    putStrLn $ "exiting gracefully after counting up some numbers" 
    performGC 
    forM_ [1..10] $ \i -> do 
    print i 
    threadDelay 10000 -- 0.05 seconds 
    where 
    loop conn = do 

     e <- tryR . (>>= evaluate) . runRedis conn $ ping 

     case e of 
     Right x -> do print x 
         threadDelay 1000000 
         loop conn 
     Left err -> do putStrLn $ "tryR caught exception: " ++ show err 

它打印:

Right Pong 
Right Pong <-------------- after this I Ctrl-C the redis server 
tryR caught exception: ConnectionLost 
exiting gracefully after counting up some numbers 
1 
test: ConnectionLost 
2 
3 
4 
5 
6 
7 
8 
9 
10 

这看起来像是在栈(如果你使用GHCI/runghc或test.hs: ConnectionLost)是印刷本test: ConnectionLost异步

如果这是GHC,这可能是一个错误,但机会很高,它由hedis或其依赖项之一完成(我自己还没有发现它在hedis本身)。

+0

另外,考虑为[hedis](https://github.com/informatikr/hedis/issues)打开一个问题来澄清它是hedis还是它的一个依赖关系。 – nh2