summaryrefslogtreecommitdiff
path: root/src/Language
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2019-07-19 06:38:54 +0200
committerEugen Wissner <belka@caraus.de>2019-07-19 06:38:54 +0200
commit5cf10b38ec95d60922caf6cf0c9a6fd1cb0e54e4 (patch)
tree45e950cd80aebdd84fabf0509e20b13e46e14c52 /src/Language
parentbc6a7dddd1f4db7a6e43085abdd25a5a4c8692cb (diff)
downloadgraphql-5cf10b38ec95d60922caf6cf0c9a6fd1cb0e54e4.tar.gz
Report parse errors with line and column numbers
Diffstat (limited to 'src/Language')
-rw-r--r--src/Language/GraphQL.hs6
-rw-r--r--src/Language/GraphQL/Error.hs26
2 files changed, 24 insertions, 8 deletions
diff --git a/src/Language/GraphQL.hs b/src/Language/GraphQL.hs
index 7a0163d..7ac08d7 100644
--- a/src/Language/GraphQL.hs
+++ b/src/Language/GraphQL.hs
@@ -8,9 +8,7 @@ import Control.Monad.IO.Class (MonadIO)
import qualified Data.Text as T
import qualified Data.Aeson as Aeson
-import Text.Megaparsec ( errorBundlePretty
- , parse
- )
+import Text.Megaparsec (parse)
import Language.GraphQL.Execute
import Language.GraphQL.Parser
@@ -34,5 +32,5 @@ graphql = flip graphqlSubs $ const Nothing
-- Returns the response as an @Aeson.@'Aeson.Value'.
graphqlSubs :: MonadIO m => Schema m -> Subs -> T.Text -> m Aeson.Value
graphqlSubs schema f =
- either (parseError . errorBundlePretty) (execute schema f)
+ either parseError (execute schema f)
. parse document ""
diff --git a/src/Language/GraphQL/Error.hs b/src/Language/GraphQL/Error.hs
index 8289f79..69fc8db 100644
--- a/src/Language/GraphQL/Error.hs
+++ b/src/Language/GraphQL/Error.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
module Language.GraphQL.Error
( parseError
, CollectErrsT
@@ -9,17 +10,34 @@ module Language.GraphQL.Error
) where
import qualified Data.Aeson as Aeson
-import Data.Text (Text, pack)
+import Data.Text (Text)
+import Data.Void (Void)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.State ( StateT
, modify
, runStateT
)
+import Text.Megaparsec ( ParseErrorBundle(..)
+ , SourcePos(..)
+ , errorOffset
+ , parseErrorTextPretty
+ , reachOffset
+ , unPos
+ )
-- | 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])]
+parseError :: Applicative f => ParseErrorBundle Text Void -> f Aeson.Value
+parseError ParseErrorBundle{..} =
+ pure $ Aeson.object [("errors", Aeson.toJSON $ fst $ foldl go ([], bundlePosState) bundleErrors)]
+ where
+ errorObject s SourcePos{..} = Aeson.object
+ [ ("message", Aeson.toJSON $ init $ parseErrorTextPretty s)
+ , ("line", Aeson.toJSON $ unPos sourceLine)
+ , ("column", Aeson.toJSON $ unPos sourceColumn)
+ ]
+ go (result, state) x =
+ let (sourcePosition, _, newState) = reachOffset (errorOffset x) state
+ in (errorObject x sourcePosition : result, newState)
-- | A wrapper to pass error messages around.
type CollectErrsT m = StateT [Aeson.Value] m