How to Handle Specific Networking Exceptions in Haskell

exceptionshaskell

I have the following to try and connect to a server:

testAddress :: HostName -> Int -> IO (Maybe Handle)
testAddress host iPort = do
    let port = PortNumber $ fromIntegral iPort
    putStrLn $ "Testing - Host: " ++ host ++ ", Port: " ++ show iPort
    result <- try $ connectTo host port
    case result of
        Left (SomeException e) -> return Nothing
        Right h -> do
            putStrLn $ "Connected to " ++ host
            return $ Just h

I made the exception to catch "SomeException", but I know that's not the proper way to do it; as it will catch everything, and you can't handle individual cases. I can't find the names of specific network exceptions though. There doesn't appear to be any documentation for the Network package, and a every example I can find on google just uses "SomeException". If I try and connect to a random host and port, and I don't attempt to catch anything, I get the error:
"* Exception: connect: failed (Connection timed out (WSAETIMEDOUT))"
But it doesn't seem to give me the exact name of the exception to try and catch. I thought it might be "WSAETIMEOUT", but when I tried catching that, I got a compilation error saying that it couldn't find the constructor for "WSAETIMEOUT".
What should I do. I don't want to just catch everything and treat it the same, because then I don't know whats going on.

Thank you

Best Answer

You can pattern-match on a specific exception type like this:

testAddress :: HostName -> Int -> IO (Maybe Handle)
testAddress host iPort = do
    let port = PortNumber $ fromIntegral iPort
    putStrLn $ "Testing - Host: " ++ host ++ ", Port: " ++ show iPort
    result <- try $ connectTo host port
    case result of
        Left (e :: MyExceptionType) -> return Nothing
        Right h -> do
            putStrLn $ "Connected to " ++ host
            return $ Just h

This will actually cause Haskell to infer that the type of result is Either MyExceptionType Handle, and try will therefore only catch exceptions of MyExceptionType, propagating all others unchanged.

As for the particular exception types used by the network package, I couldn't find any documentation on them either, but since Typeable is a superclass of Exception, you should be able to print out the type of any exception you catch, which should be useful.

Related Topic