summaryrefslogtreecommitdiff
path: root/Data/GraphQL/Error.hs
diff options
context:
space:
mode:
authorDanny Navarro <j@dannynavarro.net>2016-03-15 14:02:34 +0100
committerDanny Navarro <j@dannynavarro.net>2016-03-15 14:02:34 +0100
commit77853b17ae1197ba075ccc68df2a949dffc97092 (patch)
tree6e8385c5522ea92e4be314493c244c0ec043c568 /Data/GraphQL/Error.hs
parentd8a731fe30ce800ac8347a902f38373d6cf689b2 (diff)
parent61d6af777897d918decc0ab8ef6456e05fccbe7b (diff)
downloadgraphql-77853b17ae1197ba075ccc68df2a949dffc97092.tar.gz
Merge branch 'all-improvements'
This adds general API documentation, a tutorial and error handling.
Diffstat (limited to 'Data/GraphQL/Error.hs')
-rw-r--r--Data/GraphQL/Error.hs63
1 files changed, 63 insertions, 0 deletions
diff --git a/Data/GraphQL/Error.hs b/Data/GraphQL/Error.hs
new file mode 100644
index 0000000..74f08e4
--- /dev/null
+++ b/Data/GraphQL/Error.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Data.GraphQL.Error (
+ parseError,
+ CollectErrsT,
+ addErr,
+ addErrMsg,
+ runCollectErrs,
+ joinErrs,
+ errWrap
+ ) where
+
+import qualified Data.Aeson as Aeson
+import Data.Text (Text, pack)
+
+import Control.Arrow ((&&&))
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative (Applicative, pure)
+import Data.Foldable (Foldable, concatMap)
+import Prelude hiding (concatMap)
+#endif
+
+-- | Wraps a parse error into a list of errors.
+parseError :: Applicative f => String -> f Aeson.Value
+parseError s =
+ pure $ Aeson.object [("errors", Aeson.toJSON [makeErrorMsg $ pack s])]
+
+-- | A wrapper for an 'Applicative' to pass error messages around.
+type CollectErrsT f a = f (a,[Aeson.Value])
+
+-- | Takes a (wrapped) list (foldable functor) of values and errors,
+-- joins the values into a list and concatenates the errors.
+joinErrs
+ :: (Functor m, Functor f, Foldable f)
+ => m (f (a,[Aeson.Value])) -> CollectErrsT m (f a)
+joinErrs = fmap $ fmap fst &&& concatMap snd
+
+-- | Wraps the given 'Applicative' to handle errors
+errWrap :: Functor f => f a -> f (a, [Aeson.Value])
+errWrap = fmap (flip (,) [])
+
+-- | Adds an error to the list of errors.
+addErr :: Functor f => Aeson.Value -> CollectErrsT f a -> CollectErrsT f a
+addErr v = (fmap . fmap) (v :)
+
+makeErrorMsg :: Text -> Aeson.Value
+makeErrorMsg s = Aeson.object [("message",Aeson.toJSON s)]
+
+-- | Convenience function for just wrapping an error message.
+addErrMsg :: Functor f => Text -> CollectErrsT f a -> CollectErrsT f a
+addErrMsg = addErr . makeErrorMsg
+
+-- | Runs the given query, but collects the errors into an error
+-- list which is then sent back with the data.
+runCollectErrs :: Functor f => CollectErrsT f Aeson.Value -> f Aeson.Value
+runCollectErrs = fmap finalD
+ where
+ finalD (dat,errs) =
+ Aeson.object
+ $ if null errs
+ then [("data",dat)]
+ else [("data",dat),("errors",Aeson.toJSON $ reverse errs)]