module Client.EventLoop.Errors
( exceptionToLines
) where
import Control.Exception
import Data.List.NonEmpty (NonEmpty(..))
import Network.Socks5
import OpenSSL.Session
import Hookup
exceptionToLines ::
SomeException ->
NonEmpty String
exceptionToLines
= indentMessages
. exceptionToLines'
indentMessages :: NonEmpty String -> NonEmpty String
indentMessages (x :| xs) = x :| map ("⋯ "++) xs
exceptionToLines' ::
SomeException ->
NonEmpty String
exceptionToLines' ex
| Just err <- fromException ex = explainHookupError err
| Just err <- fromException ex :: Maybe ConnectionAbruptlyTerminated =
"Connection abruptly terminated" :| []
| Just (ProtocolError e) <- fromException ex =
("TLS protocol error: " ++ e) :| []
| Just err <- fromException ex = explainSocksError err :| []
| Just ioe <- fromException ex =
explainIOError ioe :| []
| otherwise = displayException ex :| []
explainIOError :: IOError -> String
explainIOError ioe = "IO error: " ++ displayException ioe
explainHookupError :: ConnectionFailure -> NonEmpty String
explainHookupError e =
case e of
HostnameResolutionFailure ioe ->
("Host not resolved: " ++ displayException ioe) :| []
ConnectionFailure exs ->
"Connect failed" :| map explainIOError exs
LineTooLong ->
"IRC message too long" :| []
LineTruncated ->
"IRC message incomplete" :| []
explainSocksError :: SocksError -> String
explainSocksError ex =
case ex of
SocksErrorGeneralServerFailure -> "SOCKS: General server failure"
SocksErrorConnectionNotAllowedByRule -> "SOCKS: Connection not allowed by rule"
SocksErrorNetworkUnreachable -> "SOCKS: Network unreachable"
SocksErrorHostUnreachable -> "SOCKS: Host unreachable"
SocksErrorConnectionRefused -> "SOCKS: Connection refused"
SocksErrorTTLExpired -> "SOCKS: TTL Expired"
SocksErrorCommandNotSupported -> "SOCKS: Command not supported"
SocksErrorAddrTypeNotSupported -> "SOCKS: Address type not supported"
SocksErrorOther n -> "SOCKS: Unknown error " ++ show n