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