@@ -56,7 +56,7 @@ import qualified Data.Text as T
56import Data.Typeable
56import Data.Typeable
57import GHC.Generics
57import GHC.Generics
58import GHC.TypeLits
58import GHC.TypeLits
59− (KnownNat, KnownSymbol, natVal, symbolVal)
59+ (KnownNat, KnownSymbol, TypeError, natVal, symbolVal)
60import qualified Network.HTTP.Media as NHM
60import qualified Network.HTTP.Media as NHM
61import Network.HTTP.Types hiding
61import Network.HTTP.Types hiding
62 (Header, ResponseHeaders)
62 (Header, ResponseHeaders)
@@ -88,6 +88,7 @@ import Servant.API.Modifiers
88import Servant.API.ResponseHeaders
88import Servant.API.ResponseHeaders
89 (GetHeaders, Headers, getHeaders, getResponse)
89 (GetHeaders, Headers, getHeaders, getResponse)
90import qualified Servant.Types.SourceT as S
90import qualified Servant.Types.SourceT as S
91+import Servant.API.TypeErrors
91import Web.HttpApiData
92import Web.HttpApiData
92 (FromHttpApiData, parseHeader, parseQueryParam, parseUrlPiece,
93 (FromHttpApiData, parseHeader, parseQueryParam, parseUrlPiece,
93 parseUrlPieces)
94 parseUrlPieces)
@@ -812,38 +813,15 @@ instance (HasContextEntry context (NamedContext name subContext), HasServer subA
812 hoistServerWithContext _ _ nt s = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s
813 hoistServerWithContext _ _ nt s = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s
814-------------------------------------------------------------------------------
815-------------------------------------------------------------------------------
815−-- TypeError helpers
816+-- Custom type errors
816-------------------------------------------------------------------------------
817-------------------------------------------------------------------------------
818−-- | This instance catches mistakes when there are non-saturated
819+-- Erroring instance for 'HasServer' when a combinator is not fully applied
819−-- type applications on LHS of ':>'.
821−-- >>> serve (Proxy :: Proxy (Capture "foo" :> Get '[JSON] Int)) (error "...")
823−-- ...Expected something of kind Symbol or *, got: k -> l on the LHS of ':>'.
824−-- ...Maybe you haven't applied enough arguments to
825−-- ...Capture' '[] "foo"
828−-- >>> undefined :: Server (Capture "foo" :> Get '[JSON] Int)
830−-- ...Expected something of kind Symbol or *, got: k -> l on the LHS of ':>'.
831−-- ...Maybe you haven't applied enough arguments to
832−-- ...Capture' '[] "foo"
835−instance TypeError (HasServerArrowKindError arr) => HasServer ((arr :: k -> l) :> api) context
820+instance TypeError (PartialApplication HasServer arr) => HasServer ((arr :: a -> b) :> sub) context
837− type ServerT (arr :> api) m = TypeError (HasServerArrowKindError arr)
822+ type ServerT (arr :> sub) _ = TypeError (PartialApplication HasServer arr)
838− -- it doesn't really matter what sub route we peak
823+ route = error "unreachable"
839− route _ _ _ = error "servant-server panic: impossible happened in HasServer (arr :> api)"
840− hoistServerWithContext _ _ _ = id
824+ hoistServerWithContext _ _ _ _ = error "unreachable"
842−-- Cannot have TypeError here, otherwise use of this symbol will error :)
843−type HasServerArrowKindError arr =
844− 'Text "Expected something of kind Symbol or *, got: k -> l on the LHS of ':>'."
845− ':$$: 'Text "Maybe you haven't applied enough arguments to"
848-- | This instance prevents from accidentally using '->' instead of ':>'
826-- | This instance prevents from accidentally using '->' instead of ':>'
@@ -878,6 +856,15 @@ type HasServerArrowTypeError a b =
878 ':$$: 'Text "and"
856 ':$$: 'Text "and"
879 ':$$: 'ShowType b
857 ':$$: 'ShowType b
859+-- Erroring instances for 'HasServer' for unknown API combinators
861+-- XXX: This omits the @context@ parameter, e.g.:
863+-- "There is no instance for HasServer (Bool :> …)". Do we care ?
864+instance {-# OVERLAPPABLE #-} TypeError (NoInstanceForSub HasServer ty) => HasServer (ty :> sub) context
866+instance {-# OVERLAPPABLE #-} TypeError (NoInstanceFor (HasServer api context)) => HasServer api context
881-- | Ignore @'Fragment'@ in server handlers.
868-- | Ignore @'Fragment'@ in server handlers.
882-- See <https://ietf.org/rfc/rfc2616.html#section-15.1.3> for more details.
869-- See <https://ietf.org/rfc/rfc2616.html#section-15.1.3> for more details.