diff options
Diffstat (limited to 'Data/GraphQL/Error.hs')
| -rw-r--r-- | Data/GraphQL/Error.hs | 76 |
1 files changed, 38 insertions, 38 deletions
diff --git a/Data/GraphQL/Error.hs b/Data/GraphQL/Error.hs index b19047b..08d1622 100644 --- a/Data/GraphQL/Error.hs +++ b/Data/GraphQL/Error.hs @@ -1,57 +1,57 @@ {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TupleSections #-} -module Data.GraphQL.Error ( - parseError, - CollectErrsT, - addErr, - addErrMsg, - runCollectErrs, - joinErrs, - errWrap +module Data.GraphQL.Error + ( parseError + , CollectErrsT + , addErr + , addErrMsg + , runCollectErrs + , runAppendErrs ) where import qualified Data.Aeson as Aeson import Data.Text (Text, pack) - -import Control.Arrow ((&&&)) +import Control.Monad.Trans.Class (lift) +import Control.Monad.Trans.State ( StateT + , modify + , runStateT + ) -- | 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 (, []) +-- | A wrapper to pass error messages around. +type CollectErrsT m = StateT [Aeson.Value] m -- | Adds an error to the list of errors. -addErr :: Functor f => Aeson.Value -> CollectErrsT f a -> CollectErrsT f a -addErr v = (fmap . fmap) (v :) +addErr :: Monad m => Aeson.Value -> CollectErrsT m () +addErr v = modify (v :) makeErrorMsg :: Text -> Aeson.Value -makeErrorMsg s = Aeson.object [("message",Aeson.toJSON s)] +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 :: Monad m => Text -> CollectErrsT m () 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)] +-- | Appends the given list of errors to the current list of errors. +appendErrs :: Monad m => [Aeson.Value] -> CollectErrsT m () +appendErrs errs = modify (errs ++) + +-- | Runs the given query computation, but collects the errors into an error +-- list, which is then sent back with the data. +runCollectErrs :: Monad m => CollectErrsT m Aeson.Value -> m Aeson.Value +runCollectErrs res = do + (dat, errs) <- runStateT res [] + if null errs + then return $ Aeson.object [("data", dat)] + else return $ Aeson.object [("data", dat), ("errors", Aeson.toJSON $ reverse errs)] + +-- | Runs the given computation, collecting the errors and appending them +-- to the previous list of errors. +runAppendErrs :: Monad m => CollectErrsT m a -> CollectErrsT m a +runAppendErrs f = do + (v, errs) <- lift $ runStateT f [] + appendErrs errs + return v |
