Handle errors using custom types

Fixes #32.
This commit is contained in:
2020-07-05 14:36:00 +02:00
parent b5157e141e
commit a6f9cec413
7 changed files with 119 additions and 97 deletions

View File

@ -1,10 +1,9 @@
-- | This module provides functions to execute a @GraphQL@ request.
module Language.GraphQL.Execute
( execute
, executeWithName
, module Language.GraphQL.Execute.Coerce
) where
import qualified Data.Aeson as Aeson
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.Sequence (Seq(..))
@ -18,54 +17,38 @@ import qualified Language.GraphQL.Type.Definition as Definition
import qualified Language.GraphQL.Type.Out as Out
import Language.GraphQL.Type.Schema
-- | The substitution is applied to the document, and the resolvers are applied
-- to the resulting fields.
--
-- Returns the result of the query against the schema wrapped in a /data/
-- field, or errors wrapped in an /errors/ field.
execute :: (Monad m, VariableValue a)
=> Schema m -- ^ Resolvers.
-> HashMap.HashMap Name a -- ^ Variable substitution function.
-> Document -- @GraphQL@ document.
-> m Aeson.Value
execute schema = executeRequest schema Nothing
-- | The substitution is applied to the document, and the resolvers are applied
-- to the resulting fields. The operation name can be used if the document
-- defines multiple root operations.
--
-- Returns the result of the query against the schema wrapped in a /data/
-- field, or errors wrapped in an /errors/ field.
executeWithName :: (Monad m, VariableValue a)
=> Schema m -- ^ Resolvers
-> Text -- ^ Operation name.
execute :: (Monad m, VariableValue a, Serialize b)
=> Schema m -- ^ Resolvers.
-> Maybe Text -- ^ Operation name.
-> HashMap.HashMap Name a -- ^ Variable substitution function.
-> Document -- ^ @GraphQL@ Document.
-> m Aeson.Value
executeWithName schema operationName =
executeRequest schema (Just operationName)
executeRequest :: (Monad m, VariableValue a)
=> Schema m
-> Maybe Text
-> HashMap.HashMap Name a
-> Document
-> m Aeson.Value
executeRequest schema operationName subs document =
-> Document -- @GraphQL@ document.
-> m (Response b)
execute schema operationName subs document =
case Transform.document schema operationName subs document of
Left queryError -> pure $ singleError $ Transform.queryError queryError
Right (Transform.Document types' rootObjectType operation)
| (Transform.Query _ fields) <- operation ->
executeOperation types' rootObjectType fields
| (Transform.Mutation _ fields) <- operation ->
executeOperation types' rootObjectType fields
Right transformed -> executeRequest transformed
executeRequest :: (Monad m, Serialize a)
=> Transform.Document m
-> m (Response a)
executeRequest (Transform.Document types' rootObjectType operation)
| (Transform.Query _ fields) <- operation =
executeOperation types' rootObjectType fields
| (Transform.Mutation _ fields) <- operation =
executeOperation types' rootObjectType fields
-- This is actually executeMutation, but we don't distinguish between queries
-- and mutations yet.
executeOperation :: Monad m
executeOperation :: (Monad m, Serialize a)
=> HashMap Name (Type m)
-> Out.ObjectType m
-> Seq (Transform.Selection m)
-> m Aeson.Value
-> m (Response a)
executeOperation types' objectType fields =
runCollectErrs types' $ executeSelectionSet Definition.Null objectType fields