@@ -17,6 +17,8 @@ import Prelude.Compat
18import Control.DeepSeq
18import Control.DeepSeq
19 (NFData (..))
19 (NFData (..))
20+import Control.Exception
20import Control.Monad.Catch
22import Control.Monad.Catch
21 (Exception)
23 (Exception)
22import Data.Bifoldable
24import Data.Bifoldable
@@ -66,19 +68,33 @@ data ServantError =
66 -- | The content-type header is invalid
68 -- | The content-type header is invalid
67 | InvalidContentTypeHeader Response
69 | InvalidContentTypeHeader Response
68 -- | There was a connection error, and no response was received
70 -- | There was a connection error, and no response was received
69− | ConnectionError Text
71+ | ConnectionError SomeException
70− deriving (Eq, Show, Generic, Typeable)
72+ deriving (Show, Generic, Typeable)
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 _ == ConnectionError _ = True
81+ -- prevent wild card blindness
82+ FailureResponse {} == _ = False
83+ DecodeFailure {} == _ = False
84+ UnsupportedContentType {} == _ = False
85+ InvalidContentTypeHeader {} == _ = False
86+ ConnectionError {} == _ = False
72instance Exception ServantError
88instance Exception ServantError
90+-- | Note: an exception in 'ConnectionError' might not be evaluated fully,
91+-- We only 'rnf' its 'show'ed value.
74instance NFData ServantError where
92instance NFData ServantError where
75 rnf (FailureResponse req res) = rnf req `seq` rnf res
93 rnf (FailureResponse req res) = rnf req `seq` rnf res
76 rnf (DecodeFailure err res) = rnf err `seq` rnf res
94 rnf (DecodeFailure err res) = rnf err `seq` rnf res
77− rnf (UnsupportedContentType mt' res) =
95+ rnf (UnsupportedContentType mt' res) = mediaTypeRnf mt' `seq` rnf res
78− mediaTypeRnf mt' `seq`
80 rnf (InvalidContentTypeHeader res) = rnf res
96 rnf (InvalidContentTypeHeader res) = rnf res
81− rnf (ConnectionError err) = rnf err
97+ rnf (ConnectionError err) = err `seq` rnf (show err)
83mediaTypeRnf :: MediaType -> ()
99mediaTypeRnf :: MediaType -> ()
84mediaTypeRnf mt =
100mediaTypeRnf mt =