@@ -17,6 +17,8 @@ import Prelude.Compat
1717
1818import Control.DeepSeq
1919 (NFData (..))
20+import Control.Exception
21+ (SomeException (..))
2022import Control.Monad.Catch
2123 (Exception)
2224import Data.Bifoldable
@@ -38,7 +40,7 @@ import Data.Text
3840import Data.Text.Encoding
3941 (encodeUtf8)
4042import Data.Typeable
41− (Typeable)
43+ (Typeable, typeOf)
4244import GHC.Generics
4345 (Generic)
4446import Network.HTTP.Media
@@ -66,19 +68,36 @@ data ServantError =
6668 -- | The content-type header is invalid
6769 | InvalidContentTypeHeader Response
6870 -- | There was a connection error, and no response was received
69− | ConnectionError Text
70− deriving (Eq, Show, Generic, Typeable)
71+ | ConnectionError SomeException
72+ deriving (Show, Generic, Typeable)
73+
74+instance Eq ServantError where
75+ FailureResponse req res == FailureResponse req' res' = req == req' && res == res'
76+ DecodeFailure t r == DecodeFailure t' r' = t == t' && r == r'
77+ UnsupportedContentType mt r == UnsupportedContentType mt' r' = mt == mt' && r == r'
78+ InvalidContentTypeHeader r == InvalidContentTypeHeader r' = r == r'
79+ ConnectionError exc == ConnectionError exc' = eqSomeException exc exc'
80+ where
81+ -- returns true, if type of exception is the same
82+ eqSomeException (SomeException a) (SomeException b) = typeOf a == typeOf b
83+
84+ -- prevent wild card blindness
85+ FailureResponse {} == _ = False
86+ DecodeFailure {} == _ = False
87+ UnsupportedContentType {} == _ = False
88+ InvalidContentTypeHeader {} == _ = False
89+ ConnectionError {} == _ = False
7190
7291instance Exception ServantError
7392
93+-- | Note: an exception in 'ConnectionError' might not be evaluated fully,
94+-- We only 'rnf' its 'show'ed value.
7495instance NFData ServantError where
7596 rnf (FailureResponse req res) = rnf req `seq` rnf res
7697 rnf (DecodeFailure err res) = rnf err `seq` rnf res
77− rnf (UnsupportedContentType mt' res) =
78− mediaTypeRnf mt' `seq`
79− rnf res
98+ rnf (UnsupportedContentType mt' res) = mediaTypeRnf mt' `seq` rnf res
8099 rnf (InvalidContentTypeHeader res) = rnf res
81− rnf (ConnectionError err) = rnf err
100+ rnf (ConnectionError err) = err `seq` rnf (show err)
82101
83102mediaTypeRnf :: MediaType -> ()
84103mediaTypeRnf mt =