packages feed

servant-checked-exceptions 0.4.1.0 → 1.0.0.0

raw patch · 10 files changed

+324/−33 lines, 10 filesdep +http-typesdep ~servantdep ~servant-clientdep ~servant-docsPVP ok

version bump matches the API change (PVP)

Dependencies added: http-types

Dependency ranges changed: servant, servant-client, servant-docs, servant-server

API changes (from Hackage documentation)

- Servant.Checked.Exceptions.Internal.Product: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (GHC.Show.Show (f a1), GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f as)) => GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f (a1 : as))
- Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> GHC.Types.*) (a :: u) (b :: u) (c :: u) (d :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b, f c, f d) f '[a, b, c, d]
- Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> GHC.Types.*) (a :: u) (b :: u) (c :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b, f c) f '[a, b, c]
- Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> GHC.Types.*) (a :: u) (b :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b) f '[a, b]
- Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> GHC.Types.*) (a :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a) f '[a]
- Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> GHC.Types.*). GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f '[])
- Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k e (api :: k). Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api)
- Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k k1 (api :: k1) (apis :: k). Servant.Client.HasClient (api Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> apis)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> (api Servant.API.Sub.:> apis))
- Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k k1 (es :: [GHC.Types.*]) (api :: k1) (apis :: k). Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.ThrowingNonterminal (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))
- Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [GHC.Types.*]) (es :: [*]) a. Servant.Client.HasClient (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
- Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [GHC.Types.*]) a. Servant.Client.HasClient (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope '[] a)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
- Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k (es :: [GHC.Types.*]) e (api :: k). Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing (Servant.Checked.Exceptions.Internal.Util.Snoc es e) Servant.API.Sub.:> api) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api))
- Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k e (api :: k). Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api)
- Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k k1 (ctypes :: k1). Servant.Checked.Exceptions.Internal.Servant.Docs.CreateRespBodiesFor '[] ctypes
- Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 (es :: [*]) (ctypes :: [GHC.Types.*]) (method :: k1) (status :: GHC.Types.Nat) a. (Servant.Checked.Exceptions.Internal.Servant.Docs.CreateRespBodiesFor es ctypes, Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a))) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
- Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [GHC.Types.*]) a. Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope '[] a)) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
- Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k e (api :: k) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api) context
- Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k k1 (api :: k1) (apis :: k) (context :: [*]). Servant.Server.Internal.HasServer (api Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> apis)) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> (api Servant.API.Sub.:> apis)) context
- Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k k1 (es :: [GHC.Types.*]) (api :: k1) (apis :: k) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.ThrowingNonterminal (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis)) context
- Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [GHC.Types.*]) (es :: [*]) a (context :: [*]). Servant.Server.Internal.HasServer (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a)) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a) context
- Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [GHC.Types.*]) a (context :: [*]). Servant.Server.Internal.HasServer (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope '[] a)) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a) context
- Servant.Checked.Exceptions.Internal.Union: instance forall a (a1 :: a) (as :: [a]). Servant.Checked.Exceptions.Internal.Union.UElem a1 (a1 : as) 'Servant.Checked.Exceptions.Internal.Union.Z
- Servant.Checked.Exceptions.Internal.Union: instance forall a (a1 :: a) (b :: a) (as :: [a]) (i :: Servant.Checked.Exceptions.Internal.Union.Nat). (Servant.Checked.Exceptions.Internal.Union.RIndex a1 (b : as) ~ 'Servant.Checked.Exceptions.Internal.Union.S i, Servant.Checked.Exceptions.Internal.Union.UElem a1 as i) => Servant.Checked.Exceptions.Internal.Union.UElem a1 (b : as) ('Servant.Checked.Exceptions.Internal.Union.S i)
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (Control.DeepSeq.NFData (f a1), Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (Data.Aeson.Types.FromJSON.FromJSON (f a1), Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (Data.Aeson.Types.ToJSON.ToJSON (f a1), Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (GHC.Classes.Eq (f a1), GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (GHC.Classes.Ord (f a1), GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (GHC.Read.Read (f a1), GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall a (f :: a -> *) (a1 :: a) (as :: [a]). (GHC.Show.Show (f a1), GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f (a1 : as))
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> GHC.Types.*). GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions: class ErrStatus e
+ Servant.Checked.Exceptions: data Status :: *
+ Servant.Checked.Exceptions: data VerbWithErr (method :: k1) (successStatusCode :: Nat) (contentTypes :: [*]) (es :: [*]) a
+ Servant.Checked.Exceptions: toErrStatus :: ErrStatus e => e -> Status
+ Servant.Checked.Exceptions: type DeleteAcceptedWithErr = VerbWithErr 'DELETE 202
+ Servant.Checked.Exceptions: type DeleteNoContentWithErr = VerbWithErr 'DELETE 204
+ Servant.Checked.Exceptions: type DeleteNonAuthoritativeWithErr = VerbWithErr 'DELETE 203
+ Servant.Checked.Exceptions: type DeleteResetContentWithErr = VerbWithErr 'DELETE 205
+ Servant.Checked.Exceptions: type DeleteWithErr = VerbWithErr 'DELETE 200
+ Servant.Checked.Exceptions: type GetAcceptedWithErr = VerbWithErr 'GET 202
+ Servant.Checked.Exceptions: type GetNoContentWithErr = VerbWithErr 'GET 204
+ Servant.Checked.Exceptions: type GetNonAuthoritativeWithErr = VerbWithErr 'GET 203
+ Servant.Checked.Exceptions: type GetPartialContentWithErr = VerbWithErr 'GET 206
+ Servant.Checked.Exceptions: type GetResetContentWithErr = VerbWithErr 'GET 205
+ Servant.Checked.Exceptions: type GetWithErr = VerbWithErr 'GET 200
+ Servant.Checked.Exceptions: type PatchAcceptedWithErr = VerbWithErr 'PATCH 202
+ Servant.Checked.Exceptions: type PatchNoContentWithErr = VerbWithErr 'PATCH 204
+ Servant.Checked.Exceptions: type PatchNonAuthoritativeWithErr = VerbWithErr 'PATCH 203
+ Servant.Checked.Exceptions: type PatchResetContentWithErr = VerbWithErr 'PATCH 205
+ Servant.Checked.Exceptions: type PatchWithErr = VerbWithErr 'PATCH 200
+ Servant.Checked.Exceptions: type PostAcceptedWithErr = VerbWithErr 'POST 202
+ Servant.Checked.Exceptions: type PostCreatedWithErr = VerbWithErr 'POST 201
+ Servant.Checked.Exceptions: type PostNoContentWithErr = VerbWithErr 'POST 204
+ Servant.Checked.Exceptions: type PostNonAuthoritativeWithErr = VerbWithErr 'POST 203
+ Servant.Checked.Exceptions: type PostResetContentWithErr = VerbWithErr 'POST 205
+ Servant.Checked.Exceptions: type PostWithErr = VerbWithErr 'POST 200
+ Servant.Checked.Exceptions: type PutAcceptedWithErr = VerbWithErr 'PUT 202
+ Servant.Checked.Exceptions: type PutNoContentWithErr = VerbWithErr 'PUT 204
+ Servant.Checked.Exceptions: type PutNonAuthoritativeWithErr = VerbWithErr 'PUT 203
+ Servant.Checked.Exceptions: type PutResetContentWithErr = VerbWithErr 'PUT 205
+ Servant.Checked.Exceptions: type PutWithErr = VerbWithErr 'PUT 200
+ Servant.Checked.Exceptions.Internal.Product: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (GHC.Show.Show (f a2), GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f as)) => GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> *) (a :: u) (b :: u) (c :: u) (d :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b, f c, f d) f '[a, b, c, d]
+ Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> *) (a :: u) (b :: u) (c :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b, f c) f '[a, b, c]
+ Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> *) (a :: u) (b :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a, f b) f '[a, b]
+ Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> *) (a :: u). Servant.Checked.Exceptions.Internal.Product.ToProduct (f a) f '[a]
+ Servant.Checked.Exceptions.Internal.Product: instance forall u (f :: u -> *). GHC.Show.Show (Servant.Checked.Exceptions.Internal.Product.Product f '[])
+ Servant.Checked.Exceptions.Internal.Servant.API: class ErrStatus e
+ Servant.Checked.Exceptions.Internal.Servant.API: data VerbWithErr (method :: k1) (successStatusCode :: Nat) (contentTypes :: [*]) (es :: [*]) a
+ Servant.Checked.Exceptions.Internal.Servant.API: instance forall k1 (method :: k1) (successStatusCode :: GHC.Types.Nat) (contentTypes :: [*]) (es :: [*]) k (a :: k). GHC.Generics.Generic (Servant.Checked.Exceptions.Internal.Servant.API.VerbWithErr method successStatusCode contentTypes es a)
+ Servant.Checked.Exceptions.Internal.Servant.API: toErrStatus :: ErrStatus e => e -> Status
+ Servant.Checked.Exceptions.Internal.Servant.API: type DeleteAcceptedWithErr = VerbWithErr 'DELETE 202
+ Servant.Checked.Exceptions.Internal.Servant.API: type DeleteNoContentWithErr = VerbWithErr 'DELETE 204
+ Servant.Checked.Exceptions.Internal.Servant.API: type DeleteNonAuthoritativeWithErr = VerbWithErr 'DELETE 203
+ Servant.Checked.Exceptions.Internal.Servant.API: type DeleteResetContentWithErr = VerbWithErr 'DELETE 205
+ Servant.Checked.Exceptions.Internal.Servant.API: type DeleteWithErr = VerbWithErr 'DELETE 200
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetAcceptedWithErr = VerbWithErr 'GET 202
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetNoContentWithErr = VerbWithErr 'GET 204
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetNonAuthoritativeWithErr = VerbWithErr 'GET 203
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetPartialContentWithErr = VerbWithErr 'GET 206
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetResetContentWithErr = VerbWithErr 'GET 205
+ Servant.Checked.Exceptions.Internal.Servant.API: type GetWithErr = VerbWithErr 'GET 200
+ Servant.Checked.Exceptions.Internal.Servant.API: type PatchAcceptedWithErr = VerbWithErr 'PATCH 202
+ Servant.Checked.Exceptions.Internal.Servant.API: type PatchNoContentWithErr = VerbWithErr 'PATCH 204
+ Servant.Checked.Exceptions.Internal.Servant.API: type PatchNonAuthoritativeWithErr = VerbWithErr 'PATCH 203
+ Servant.Checked.Exceptions.Internal.Servant.API: type PatchResetContentWithErr = VerbWithErr 'PATCH 205
+ Servant.Checked.Exceptions.Internal.Servant.API: type PatchWithErr = VerbWithErr 'PATCH 200
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostAcceptedWithErr = VerbWithErr 'POST 202
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostCreatedWithErr = VerbWithErr 'POST 201
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostNoContentWithErr = VerbWithErr 'POST 204
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostNonAuthoritativeWithErr = VerbWithErr 'POST 203
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostResetContentWithErr = VerbWithErr 'POST 205
+ Servant.Checked.Exceptions.Internal.Servant.API: type PostWithErr = VerbWithErr 'POST 200
+ Servant.Checked.Exceptions.Internal.Servant.API: type PutAcceptedWithErr = VerbWithErr 'PUT 202
+ Servant.Checked.Exceptions.Internal.Servant.API: type PutNoContentWithErr = VerbWithErr 'PUT 204
+ Servant.Checked.Exceptions.Internal.Servant.API: type PutNonAuthoritativeWithErr = VerbWithErr 'PUT 203
+ Servant.Checked.Exceptions.Internal.Servant.API: type PutResetContentWithErr = VerbWithErr 'PUT 205
+ Servant.Checked.Exceptions.Internal.Servant.API: type PutWithErr = VerbWithErr 'PUT 200
+ Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [*]) (es :: [*]) a. Servant.Client.HasClient (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
+ Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [*]) a. Servant.Client.HasClient (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope '[] a)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
+ Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 e (api :: k1). Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api)
+ Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 k (api :: k) (apis :: k1). Servant.Client.HasClient (api Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> apis)) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> (api Servant.API.Sub.:> apis))
+ Servant.Checked.Exceptions.Internal.Servant.Client: instance forall k1 k (es :: [*]) (api :: k) (apis :: k1). Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.ThrowingNonterminal (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))) => Servant.Client.HasClient (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))
+ Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 (es :: [*]) (ctypes :: [*]) (method :: k1) (status :: GHC.Types.Nat) a. (Servant.Checked.Exceptions.Internal.Servant.Docs.CreateRespBodiesFor es ctypes, Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a))) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
+ Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 (es :: [*]) e (api :: k1). Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing (Servant.Checked.Exceptions.Internal.Util.Snoc es e) Servant.API.Sub.:> api) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api))
+ Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [*]) a. Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope '[] a)) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a)
+ Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 e (api :: k1). Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) => Servant.Docs.Internal.HasDocs (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api)
+ Servant.Checked.Exceptions.Internal.Servant.Docs: instance forall k1 k2 (ctypes :: k2). Servant.Checked.Exceptions.Internal.Servant.Docs.CreateRespBodiesFor '[] ctypes
+ Servant.Checked.Exceptions.Internal.Servant.Server: acceptCheck :: (AllMime list) => Proxy list -> ByteString -> DelayedIO ()
+ Servant.Checked.Exceptions.Internal.Servant.Server: allowedMethod :: Method -> Request -> Bool
+ Servant.Checked.Exceptions.Internal.Servant.Server: allowedMethodHead :: Method -> Request -> Bool
+ Servant.Checked.Exceptions.Internal.Servant.Server: getErrStatus :: AllErrStatus es => OpenUnion es -> Status
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [*]) (a :: k) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.VerbWithErr method status ctypes '[] a) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k k1 (method :: k1) (status :: GHC.Types.Nat) (ctypes :: [*]) (es :: [*]) (a :: k) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.VerbWithErr method status ctypes es a) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> Servant.API.Verbs.Verb method status ctypes a) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 (ctypes :: [*]) (es :: [*]) a (successStatus :: GHC.Types.Nat) (method :: k1) (context :: [*]). (Servant.API.ContentTypes.AllCTRender ctypes (Servant.Checked.Exceptions.Internal.Envelope.Envelope es a), Servant.Checked.Exceptions.Internal.Servant.API.AllErrStatus es, GHC.TypeNats.KnownNat successStatus, Servant.API.Verbs.ReflectMethod method) => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.VerbWithErr method successStatus ctypes es a) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 e (api :: k1) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing '[e] Servant.API.Sub.:> api) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throws e Servant.API.Sub.:> api) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 k (api :: k) (apis :: k1) (context :: [*]). Servant.Server.Internal.HasServer (api Servant.API.Sub.:> (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> apis)) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.NoThrow Servant.API.Sub.:> (api Servant.API.Sub.:> apis)) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: instance forall k1 k (es :: [*]) (api :: k) (apis :: k1) (context :: [*]). Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.ThrowingNonterminal (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis))) context => Servant.Server.Internal.HasServer (Servant.Checked.Exceptions.Internal.Servant.API.Throwing es Servant.API.Sub.:> (api Servant.API.Sub.:> apis)) context
+ Servant.Checked.Exceptions.Internal.Servant.Server: methodCheck :: Method -> Request -> DelayedIO ()
+ Servant.Checked.Exceptions.Internal.Servant.Server: methodRouter :: forall ctypes a es env. (AllCTRender ctypes (Envelope es a), AllErrStatus es) => Method -> Status -> Proxy ctypes -> Delayed env (Handler (Envelope es a)) -> Router' env (Request -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived)
+ Servant.Checked.Exceptions.Internal.Servant.Server: processMethodRouter :: Maybe (ByteString, ByteString) -> Status -> Method -> Maybe [(HeaderName, ByteString)] -> Request -> RouteResult Response
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (a2 :: a1) (as :: [a1]). Servant.Checked.Exceptions.Internal.Union.UElem a2 (a2 : as) 'Servant.Checked.Exceptions.Internal.Union.Z
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (a2 :: a1) (b :: a1) (as :: [a1]) (i :: Servant.Checked.Exceptions.Internal.Union.Nat). (Servant.Checked.Exceptions.Internal.Union.RIndex a2 (b : as) ~ 'Servant.Checked.Exceptions.Internal.Union.S i, Servant.Checked.Exceptions.Internal.Union.UElem a2 as i) => Servant.Checked.Exceptions.Internal.Union.UElem a2 (b : as) ('Servant.Checked.Exceptions.Internal.Union.S i)
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (Control.DeepSeq.NFData (f a2), Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (Data.Aeson.Types.FromJSON.FromJSON (f a2), Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (Data.Aeson.Types.ToJSON.ToJSON (f a2), Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f as)) => Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (GHC.Classes.Eq (f a2), GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (GHC.Classes.Ord (f a2), GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (GHC.Read.Read (f a2), GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall a1 (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (GHC.Show.Show (f a2), GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f as)) => GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f (a2 : as))
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). Control.DeepSeq.NFData (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). Data.Aeson.Types.FromJSON.FromJSON (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). Data.Aeson.Types.ToJSON.ToJSON (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). GHC.Classes.Eq (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). GHC.Classes.Ord (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). GHC.Read.Read (Servant.Checked.Exceptions.Internal.Union.Union f '[])
+ Servant.Checked.Exceptions.Internal.Union: instance forall u (f :: u -> *). GHC.Show.Show (Servant.Checked.Exceptions.Internal.Union.Union f '[])
- Servant.Checked.Exceptions: class i ~ RIndex a as => UElem (a :: u) (as :: [u]) (i :: Nat) where unionPrism = prism' unionLift unionMatch unionLift = review unionPrism unionMatch = preview unionPrism
+ Servant.Checked.Exceptions: class i ~ RIndex a as => UElem (a :: u) (as :: [u]) (i :: Nat)
- Servant.Checked.Exceptions.Internal.Union: class i ~ RIndex a as => UElem (a :: u) (as :: [u]) (i :: Nat) where unionPrism = prism' unionLift unionMatch unionLift = review unionPrism unionMatch = preview unionPrism
+ Servant.Checked.Exceptions.Internal.Union: class i ~ RIndex a as => UElem (a :: u) (as :: [u]) (i :: Nat)

Files

CHANGELOG.md view
@@ -1,4 +1,10 @@ +## 1.0.0.0++*   Add a `ErrStatus` class that can be used to set the HTTP Status Code. Given+    an endpoint that returns a `Envelope '[e1, e2] a`, you must declare an+    instance of `ErrStatus` for `e1` and `e2`.  This is a breaking change.+ ## 0.4.1.0  *   Add `NoThrow` type to represent handlers that don't throw any errors, but
README.md view
@@ -131,7 +131,7 @@ $ curl \     --request POST \     --header 'Accept: application/json' \-    'http://localhost:8201/lax-search/hello'+    'http://localhost:8201/lax-search/goodbye' {"err":"BadSearchTermErr"} ``` 
example/Api.hs view
@@ -12,11 +12,13 @@ import Data.Aeson.Types (Parser) import Data.String (IsString) import Data.Text (unpack)+import Network.HTTP.Types (Status, status400, status404) import Servant.API (Capture, JSON, Post, (:>), (:<|>)) import Text.Read (readMaybe) import Web.HttpApiData (FromHttpApiData, ToHttpApiData)  import Servant.Checked.Exceptions (NoThrow, Throws)+import Servant.Checked.Exceptions.Internal.Servant.API (ErrStatus(toErrStatus))  --------- -- API --@@ -107,6 +109,10 @@   parseJSON = withText "BadSearchTermErr" $     maybe (fail "could not parse as BadSearchTermErr") pure . readMaybe . unpack +instance ErrStatus BadSearchTermErr where+  toErrStatus :: BadSearchTermErr -> Status+  toErrStatus _ = status404+ -- | This error is returned when the search query is @\"hello\"@, but it is not -- capitalized correctly.  For example, the search query @\"hello\"@ will -- return an 'IncorrectCapitialization' error.  However, the search query@@ -121,6 +127,10 @@   parseJSON :: Value -> Parser IncorrectCapitalization   parseJSON = withText "IncorrectCapitalization" $     maybe (fail "could not parse as IncorrectCapitalization") pure . readMaybe . unpack++instance ErrStatus IncorrectCapitalization where+  toErrStatus :: IncorrectCapitalization -> Status+  toErrStatus _ = status400  ---------- -- Port --
example/Server.hs view
@@ -22,13 +22,16 @@ import Network.Wai.Handler.Warp (run) import Servant (Handler, (:<|>)((:<|>)), ServerT, serve) -import Servant.Checked.Exceptions-       (Envelope, pureErrEnvelope, pureSuccEnvelope)+import Servant.Checked.Exceptions (Envelope, pureErrEnvelope, pureSuccEnvelope)  import Api-       (Api, BadSearchTermErr(BadSearchTermErr),-        IncorrectCapitalization(IncorrectCapitalization),-        SearchQuery(SearchQuery), SearchResponse, port)+  ( Api+  , BadSearchTermErr(BadSearchTermErr)+  , IncorrectCapitalization(IncorrectCapitalization)+  , SearchQuery(SearchQuery)+  , SearchResponse+  , port+  )  -- | This is our server root for the 'ServerT' for 'Api'.  We only have two -- handlers, 'postStrictSearch' and 'postLaxSearch'.
servant-checked-exceptions.cabal view
@@ -1,5 +1,5 @@ name:                servant-checked-exceptions-version:             0.4.1.0+version:             1.0.0.0 synopsis:            Checked exceptions for Servant APIs. description:         Please see <https://github.com/cdepillabout/servant-checked-exceptions#readme README.md>. homepage:            https://github.com/cdepillabout/servant-checked-exceptions@@ -7,7 +7,7 @@ license-file:        LICENSE author:              Dennis Gosnell maintainer:          cdep.illabout@gmail.com-copyright:           2017 Dennis Gosnell+copyright:           2017-2018 Dennis Gosnell category:            Text build-type:          Simple extra-source-files:  CHANGELOG.md@@ -33,18 +33,20 @@                      , Servant.Checked.Exceptions.Internal.Servant.Server                      , Servant.Checked.Exceptions.Internal.Union                      , Servant.Checked.Exceptions.Internal.Util-  build-depends:       base >= 4.8 && < 5+  build-depends:       base >= 4.9 && < 5                      , aeson                      , bytestring                      , deepseq                      , http-media+                     , http-types                      , profunctors                      , tagged-                     , servant >= 0.9-                     , servant-client >= 0.9-                     , servant-docs >= 0.9-                     , servant-server >= 0.9+                     , servant >= 0.9 && < 0.12+                     , servant-client >= 0.9 && < 0.12+                     , servant-docs >= 0.9 && < 0.12+                     , servant-server >= 0.9 && < 0.12                      , text+                     , wai   default-language:    Haskell2010   ghc-options:         -Wall -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction   other-extensions:    QuasiQuotes@@ -58,6 +60,7 @@                      , aeson                      , http-api-data                      , http-client+                     , http-types                      , optparse-applicative                      , servant                      , servant-checked-exceptions@@ -78,6 +81,7 @@   build-depends:       base                      , aeson                      , http-api-data+                     , http-types                      , servant                      , servant-checked-exceptions                      , servant-docs@@ -97,6 +101,7 @@   build-depends:       base                      , aeson                      , http-api-data+                     , http-types                      , natural-transformation                      , servant                      , servant-checked-exceptions@@ -130,6 +135,7 @@   build-depends:       base                      , bytestring                      , hspec-wai+                     , http-types                      , tasty                      , tasty-hspec                      , tasty-hunit
src/Servant/Checked/Exceptions.hs view
@@ -90,10 +90,51 @@  module Servant.Checked.Exceptions   (-  -- * 'Throws' API parameter+  -- * Servant Types+  -- ** 'Throws' API parameter     Throws-  -- * 'NoThrow' API parameter+  -- ** 'NoThrow' API parameter   , NoThrow+  -- ** HTTP Error Status Code+  , ErrStatus(toErrStatus)+  , Status+  -- ** Verbs+  , VerbWithErr+  -- *** Specialized Verbs+  -- **** HTTP 200+  , GetWithErr+  , PostWithErr+  , PutWithErr+  , DeleteWithErr+  , PatchWithErr+  -- **** HTTP 201+  , PostCreatedWithErr+  -- **** HTTP 202+  , GetAcceptedWithErr+  , PostAcceptedWithErr+  , DeleteAcceptedWithErr+  , PatchAcceptedWithErr+  , PutAcceptedWithErr+  -- **** HTTP 203+  , GetNonAuthoritativeWithErr+  , PostNonAuthoritativeWithErr+  , DeleteNonAuthoritativeWithErr+  , PatchNonAuthoritativeWithErr+  , PutNonAuthoritativeWithErr+  -- **** HTTP 204+  , GetNoContentWithErr+  , PostNoContentWithErr+  , DeleteNoContentWithErr+  , PatchNoContentWithErr+  , PutNoContentWithErr+  -- **** HTTP 205+  , GetResetContentWithErr+  , PostResetContentWithErr+  , DeleteResetContentWithErr+  , PatchResetContentWithErr+  , PutResetContentWithErr+  -- **** HTTP 206+  , GetPartialContentWithErr   -- * 'Envelope' response wrapper   , Envelope(..)   -- ** 'Envelope' helper functions@@ -160,5 +201,7 @@   , tupleToProduct   , ReturnX   ) where++import Network.HTTP.Types (Status)  import Servant.Checked.Exceptions.Internal
src/Servant/Checked/Exceptions/Internal/Servant/API.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}@@ -18,6 +20,11 @@  module Servant.Checked.Exceptions.Internal.Servant.API where +import Data.Typeable (Typeable)+import GHC.Exts (Constraint)+import GHC.Generics (Generic)+import GHC.TypeLits (Nat)+import Network.HTTP.Types (Status, StdMethod(DELETE, GET, PATCH, POST, PUT)) import Servant.API ((:>))  import Servant.Checked.Exceptions.Internal.Util (Snoc)@@ -62,3 +69,52 @@     Throwing (Snoc es e) :> api   ThrowingNonterminal (Throwing es :> c :> api) =     c :> Throwing es :> api++data VerbWithErr+    (method :: k1)+    (successStatusCode :: Nat)+    (contentTypes :: [*])+    (es :: [*])+    a+  deriving (Generic, Typeable)++type GetWithErr    = VerbWithErr 'GET    200+type PostWithErr   = VerbWithErr 'POST   200+type PutWithErr    = VerbWithErr 'PUT    200+type DeleteWithErr = VerbWithErr 'DELETE 200+type PatchWithErr  = VerbWithErr 'PATCH  200++type PostCreatedWithErr = VerbWithErr 'POST 201++type GetAcceptedWithErr    = VerbWithErr 'GET 202+type PostAcceptedWithErr   = VerbWithErr 'POST 202+type DeleteAcceptedWithErr = VerbWithErr 'DELETE 202+type PatchAcceptedWithErr  = VerbWithErr 'PATCH 202+type PutAcceptedWithErr    = VerbWithErr 'PUT 202++type GetNonAuthoritativeWithErr    = VerbWithErr 'GET 203+type PostNonAuthoritativeWithErr   = VerbWithErr 'POST 203+type DeleteNonAuthoritativeWithErr = VerbWithErr 'DELETE 203+type PatchNonAuthoritativeWithErr  = VerbWithErr 'PATCH 203+type PutNonAuthoritativeWithErr    = VerbWithErr 'PUT 203++type GetNoContentWithErr    = VerbWithErr 'GET 204+type PostNoContentWithErr   = VerbWithErr 'POST 204+type DeleteNoContentWithErr = VerbWithErr 'DELETE 204+type PatchNoContentWithErr  = VerbWithErr 'PATCH 204+type PutNoContentWithErr    = VerbWithErr 'PUT 204++type GetResetContentWithErr    = VerbWithErr 'GET 205+type PostResetContentWithErr   = VerbWithErr 'POST 205+type DeleteResetContentWithErr = VerbWithErr 'DELETE 205+type PatchResetContentWithErr  = VerbWithErr 'PATCH 205+type PutResetContentWithErr    = VerbWithErr 'PUT 205++type GetPartialContentWithErr = VerbWithErr 'GET 206++class ErrStatus e where+  toErrStatus :: e -> Status++type family AllErrStatus (es :: [k]) :: Constraint where+  AllErrStatus '[] = ()+  AllErrStatus (a ': as) = (ErrStatus a, AllErrStatus as)
src/Servant/Checked/Exceptions/Internal/Servant/Server.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -26,17 +27,47 @@  module Servant.Checked.Exceptions.Internal.Servant.Server where +import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as LBS+import Data.Functor.Identity+import Data.Maybe import Data.Proxy (Proxy(Proxy))-import Servant.Server.Internal.Router (Router)-import Servant.Server.Internal.RoutingApplication (Delayed)+import GHC.TypeLits (KnownNat, natVal)+import Network.HTTP.Types+import Network.Wai+import Servant.API.ContentTypes -- (AcceptHeader(AcceptHeader), AllCTRender, handleAcceptH)+import Servant.Server.Internal (ct_wildcard)+import Servant.Server.Internal.Router (Router, Router', leafRouter)+import Servant.Server.Internal.RoutingApplication -- (Delayed, DelayedIO, RouteResult(FailFatal, Route), addAcceptCheck, addMethodCheck, runAction) import Servant-       (Context, Handler, HasServer(..), ServerT, Verb, (:>), (:<|>))+  ( (:<|>)+  , (:>)+  , Context+  , Handler+  , HasServer(..)+  , ReflectMethod+  , ServerT+  , Verb+  , err405+  , err406+  , reflectMethod+  ) -import Servant.Checked.Exceptions.Internal.Envelope (Envelope)+import Servant.Checked.Exceptions.Internal.Envelope (Envelope, envelope)+import Servant.Checked.Exceptions.Internal.Union (OpenUnion, Union(That, This)) import Servant.Checked.Exceptions.Internal.Servant.API-       (NoThrow, Throws, Throwing, ThrowingNonterminal)+  ( AllErrStatus+  , ErrStatus(toErrStatus)+  , NoThrow+  , Throwing+  , ThrowingNonterminal+  , Throws+  , VerbWithErr+  )  -- TODO: Make sure to also account for when headers are being used.+-- This might be hard to do:+-- https://github.com/cdepillabout/servant-checked-exceptions/issues/4  -- | Change a 'Throws' into 'Throwing'. instance (HasServer (Throwing '[e] :> api) context) =>@@ -54,33 +85,38 @@  -- | When @'Throwing' es@ comes before a 'Verb', change it into the same 'Verb' -- but returning an @'Envelope' es@.-instance (HasServer (Verb method status ctypes (Envelope es a)) context) =>+instance (HasServer (VerbWithErr method status ctypes es a) context) =>     HasServer (Throwing es :> Verb method status ctypes a) context where    type ServerT (Throwing es :> Verb method status ctypes a) m =-    ServerT (Verb method status ctypes (Envelope es a)) m+    ServerT (VerbWithErr method status ctypes es a) m    route     :: Proxy (Throwing es :> Verb method status ctypes a)     -> Context context-    -> Delayed env (ServerT (Verb method status ctypes (Envelope es a)) Handler)+    -> Delayed env+         (ServerT (VerbWithErr method status ctypes es a) Handler)     -> Router env-  route _ = route (Proxy :: Proxy (Verb method status ctypes (Envelope es a)))+  route _ =+    route+      (Proxy :: Proxy (VerbWithErr method status ctypes es a))  -- | When 'NoThrow' comes before a 'Verb', change it into the same 'Verb' -- but returning an @'Envelope' \'[]@.-instance (HasServer (Verb method status ctypes (Envelope '[] a)) context) =>+instance+    ( HasServer (VerbWithErr method status ctypes '[] a) context+    ) =>     HasServer (NoThrow :> Verb method status ctypes a) context where    type ServerT (NoThrow :> Verb method status ctypes a) m =-    ServerT (Verb method status ctypes (Envelope '[] a)) m+    ServerT (VerbWithErr method status ctypes '[] a) m    route     :: Proxy (NoThrow :> Verb method status ctypes a)     -> Context context-    -> Delayed env (ServerT (Verb method status ctypes (Envelope '[] a)) Handler)+    -> Delayed env (ServerT (VerbWithErr method status ctypes '[] a) Handler)     -> Router env-  route _ = route (Proxy :: Proxy (Verb method status ctypes (Envelope '[] a)))+  route _ = route (Proxy :: Proxy (VerbWithErr method status ctypes '[] a))  -- | When @'Throwing' es@ comes before ':<|>', push @'Throwing' es@ into each -- branch of the API.@@ -142,3 +178,106 @@     -> Delayed env (ServerT (api :> NoThrow :> apis) Handler)     -> Router env   route _ = route (Proxy :: Proxy (api :> NoThrow :> apis))++---------------------+-- Verb With Error --+---------------------++instance+    {-# OVERLAPPABLE #-}+    ( AllCTRender ctypes (Envelope es a)+    , AllErrStatus es+    , KnownNat successStatus+    , ReflectMethod method+    ) =>+    HasServer (VerbWithErr method successStatus ctypes es a) context where++  type ServerT (VerbWithErr method successStatus ctypes es a) m =+    m (Envelope es a)++  route+    :: Proxy (VerbWithErr method successStatus ctypes es a)+    -> Context context+    -> Delayed env (Handler (Envelope es a))+    -> Router' env+         ( Request ->+           (RouteResult Response -> IO ResponseReceived) ->+           IO ResponseReceived+         )+  route Proxy _ = methodRouter method successStatus (Proxy :: Proxy ctypes)+    where+      method :: Method+      method = reflectMethod (Proxy :: Proxy method)++      successStatus :: Status+      successStatus =+        toEnum . fromInteger $ natVal (Proxy :: Proxy successStatus)++methodRouter ::+     forall ctypes a es env.+     (AllCTRender ctypes (Envelope es a), AllErrStatus es)+  => Method+  -> Status+  -> Proxy ctypes+  -> Delayed env (Handler (Envelope es a))+  -> Router' env+       ( Request ->+         (RouteResult Response -> IO ResponseReceived)->+         IO ResponseReceived+       )+methodRouter method successStatus proxy action = leafRouter route'+  where+    route'+      :: env+      -> Request+      -> (RouteResult Response -> IO ResponseReceived)+      -> IO ResponseReceived+    route' env request respond = do+      let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request+      let theAction =+            action+              `addMethodCheck` methodCheck method request+              `addAcceptCheck` acceptCheck proxy accH+      runAction theAction env request respond $ go request accH++    go :: Request -> ByteString -> Envelope es a -> RouteResult Response+    go request accH envel = do+      let status = envelope getErrStatus (const successStatus) envel+      let handleA = handleAcceptH proxy (AcceptHeader accH) envel+      processMethodRouter handleA status method Nothing request++allowedMethod :: Method -> Request -> Bool+allowedMethod method request =+  allowedMethodHead method request || requestMethod request == method++allowedMethodHead :: Method -> Request -> Bool+allowedMethodHead method request =+  method == methodGet && requestMethod request == methodHead++methodCheck :: Method -> Request -> DelayedIO ()+methodCheck method request+  | allowedMethod method request = return ()+  | otherwise                    = delayedFail err405++acceptCheck :: (AllMime list) => Proxy list -> ByteString -> DelayedIO ()+acceptCheck proxy accH+  | canHandleAcceptH proxy (AcceptHeader accH) = return ()+  | otherwise                                  = delayedFail err406++getErrStatus :: AllErrStatus es => OpenUnion es -> Status+getErrStatus (This (Identity e)) = toErrStatus e+getErrStatus (That es) = getErrStatus es++processMethodRouter+  :: Maybe (LBS.ByteString, LBS.ByteString)+  -> Status+  -> Method+  -> Maybe [(HeaderName, ByteString)]+  -> Request -> RouteResult Response+processMethodRouter handleA status method headers request = case handleA of+  Nothing -> FailFatal err406 -- this should not happen (checked before),+                              -- so we make it fatal if it does+  Just (contentT, body) -> Route $ responseLBS status hdrs bdy+    where+      bdy = if allowedMethodHead method request then "" else body+      hdrs = (hContentType, LBS.toStrict contentT) : (fromMaybe [] headers)
stack.yaml view
@@ -1,7 +1,7 @@ # For more information, see: http://docs.haskellstack.org/en/stable/yaml_configuration.html  # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)-resolver: lts-9.2+resolver: lts-10.5  # Local packages, usually specified by relative directory name packages:
test/Spec.hs view
@@ -1,7 +1,9 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}  module Main where @@ -9,15 +11,37 @@ import Data.Proxy (Proxy(Proxy)) import Data.Type.Equality ((:~:)(Refl)) import Data.Typeable (Typeable)+import Network.HTTP.Types (status404) import Network.Wai (Application)-import Servant ((:<|>)((:<|>)), (:>), Capture, Get, Handler, JSON, ServerT, serve)-import Test.Hspec.Wai (get, shouldRespondWith, with)+import Servant+  ( (:<|>)((:<|>))+  , (:>)+  , Capture+  , Get+  , Handler+  , JSON+  , ServerT+  , serve+  )+import Test.Hspec.Wai+  ( ResponseMatcher(matchStatus)+  , get+  , shouldRespondWith+  , with+  ) import Test.Tasty (TestTree, defaultMain, testGroup) import Test.Tasty.Hspec (describe, it, testSpec) import Test.Tasty.HUnit ((@?=), assertFailure, testCase)  import Servant.Checked.Exceptions-       (Envelope, NoThrow, Throws, pureErrEnvelope, pureSuccEnvelope)+  ( Envelope+  , ErrStatus(toErrStatus)+  , NoThrow+  , Status+  , Throws+  , pureErrEnvelope+  , pureSuccEnvelope+  )  main :: IO () main = do@@ -130,6 +154,10 @@ -- Server tests -- ------------------ +instance ErrStatus Int where+  toErrStatus :: Int -> Status+  toErrStatus _ = status404+ type TestThrows = Capture "foobar" Double :> Throws Int :> Get '[JSON] String  type TestNoThrow = Capture "baz" Integer :> NoThrow :> Get '[JSON] String@@ -157,7 +185,7 @@     with (pure app) $ do       describe "Throws" $ do         it "handler can return error envelope" $-          get "/-5" `shouldRespondWith` "{\"err\":0}"+          get "/-5" `shouldRespondWith` "{\"err\":0}" { matchStatus = 404 }         it "handler can return success envelope" $           get "/10" `shouldRespondWith` "{\"data\":\"success\"}"       describe "NoThrow" $ do