2016-03-12 00:59:51 +01:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2019-06-28 11:12:28 +02:00
|
|
|
module Data.GraphQL.Error
|
|
|
|
( parseError
|
|
|
|
, CollectErrsT
|
|
|
|
, addErr
|
|
|
|
, addErrMsg
|
|
|
|
, runCollectErrs
|
|
|
|
, runAppendErrs
|
2016-03-12 00:59:51 +01:00
|
|
|
) where
|
|
|
|
|
|
|
|
import qualified Data.Aeson as Aeson
|
|
|
|
import Data.Text (Text, pack)
|
2019-06-28 11:12:28 +02:00
|
|
|
import Control.Monad.Trans.Class (lift)
|
|
|
|
import Control.Monad.Trans.State ( StateT
|
|
|
|
, modify
|
|
|
|
, runStateT
|
|
|
|
)
|
2016-03-12 00:59:51 +01:00
|
|
|
|
|
|
|
-- | 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])]
|
|
|
|
|
2019-06-28 11:12:28 +02:00
|
|
|
-- | A wrapper to pass error messages around.
|
|
|
|
type CollectErrsT m = StateT [Aeson.Value] m
|
2016-03-12 00:59:51 +01:00
|
|
|
|
|
|
|
-- | Adds an error to the list of errors.
|
2019-06-28 11:12:28 +02:00
|
|
|
addErr :: Monad m => Aeson.Value -> CollectErrsT m ()
|
|
|
|
addErr v = modify (v :)
|
2016-03-12 00:59:51 +01:00
|
|
|
|
|
|
|
makeErrorMsg :: Text -> Aeson.Value
|
2019-06-28 11:12:28 +02:00
|
|
|
makeErrorMsg s = Aeson.object [("message", Aeson.toJSON s)]
|
2016-03-12 00:59:51 +01:00
|
|
|
|
|
|
|
-- | Convenience function for just wrapping an error message.
|
2019-06-28 11:12:28 +02:00
|
|
|
addErrMsg :: Monad m => Text -> CollectErrsT m ()
|
2016-03-12 00:59:51 +01:00
|
|
|
addErrMsg = addErr . makeErrorMsg
|
|
|
|
|
2019-06-28 11:12:28 +02:00
|
|
|
-- | 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
|