diff --git a/yesod-core/ChangeLog.md b/yesod-core/ChangeLog.md index ced204143..550149041 100644 --- a/yesod-core/ChangeLog.md +++ b/yesod-core/ChangeLog.md @@ -1,5 +1,9 @@ # ChangeLog for yesod-core +## 1.6.25 + +* Support `JSONPath` in error messages [#1807](https://github.com/yesodweb/yesod/pull/1807) + ## 1.6.24.2 * No star is type [#1797](https://github.com/yesodweb/yesod/pull/1797) diff --git a/yesod-core/src/Yesod/Core/Json.hs b/yesod-core/src/Yesod/Core/Json.hs index a51f59284..2422296b0 100644 --- a/yesod-core/src/Yesod/Core/Json.hs +++ b/yesod-core/src/Yesod/Core/Json.hs @@ -11,7 +11,9 @@ module Yesod.Core.Json -- * Convert to a JSON value , parseCheckJsonBody + , iparseCheckJsonBody , parseInsecureJsonBody + , iparseInsecureJsonBody , requireCheckJsonBody , requireInsecureJsonBody -- ** Deprecated JSON conversion @@ -47,6 +49,7 @@ import Yesod.Core.Class.Handler import Yesod.Core.Widget (WidgetFor) import Yesod.Routes.Class import qualified Data.Aeson as J +import qualified Data.Aeson.Types as JT import qualified Data.Aeson.Parser as JP import Data.Aeson ((.=), object) import Data.Conduit.Attoparsec (sinkParser) @@ -99,8 +102,6 @@ provideJson :: (Monad m, J.ToJSON a) => a -> Writer (Endo [ProvidedRep m]) () provideJson = provideRep . return . J.toEncoding -- | Same as 'parseInsecureJsonBody' --- --- @since 0.3.0 parseJsonBody :: (MonadHandler m, J.FromJSON a) => m (J.Result a) parseJsonBody = parseInsecureJsonBody {-# DEPRECATED parseJsonBody "Use parseCheckJsonBody or parseInsecureJsonBody instead" #-} @@ -118,6 +119,16 @@ parseInsecureJsonBody = do Left e -> J.Error $ show e Right value -> J.fromJSON value +-- | Same as 'parseInsecureJsonBody', but returns an `IResult` +-- +-- @since 1.6.25 +iparseInsecureJsonBody :: (MonadHandler m, J.FromJSON a) => m (JT.IResult a) +iparseInsecureJsonBody = do + eValue <- runConduit $ rawRequestBody .| runCatchC (sinkParser JP.value') + return $ case eValue of + Left e -> JT.IError [] $ show e + Right value -> JT.ifromJSON value + -- | Parse the request body to a data type as a JSON value. The -- data type must support conversion from JSON via 'J.FromJSON'. -- If you want the raw JSON value, just ask for a @'J.Result' @@ -141,6 +152,16 @@ parseCheckJsonBody = do Just True -> parseInsecureJsonBody _ -> return $ J.Error $ "Non-JSON content type: " ++ show mct +-- | Same as 'parseCheckJsonBody', but returns an `IResult` +-- +-- @since 1.6.25 +iparseCheckJsonBody :: (MonadHandler m, J.FromJSON a) => m (JT.IResult a) +iparseCheckJsonBody = do + mct <- lookupHeader "content-type" + case fmap contentTypeHeaderIsJson mct of + Just True -> iparseInsecureJsonBody + _ -> return $ JT.IError [] $ "Non-JSON content type: " ++ show mct + -- | Same as 'parseInsecureJsonBody', but return an invalid args response on a parse -- error. parseJsonBody_ :: (MonadHandler m, J.FromJSON a) => m a @@ -159,19 +180,19 @@ requireJsonBody = requireInsecureJsonBody -- @since 1.6.11 requireInsecureJsonBody :: (MonadHandler m, J.FromJSON a) => m a requireInsecureJsonBody = do - ra <- parseInsecureJsonBody + ra <- iparseInsecureJsonBody case ra of - J.Error s -> invalidArgs [pack s] - J.Success a -> return a + JT.IError path s -> invalidArgs [pack (JT.formatError path s)] + JT.ISuccess a -> return a -- | Same as 'parseCheckJsonBody', but return an invalid args response on a parse -- error. requireCheckJsonBody :: (MonadHandler m, J.FromJSON a) => m a requireCheckJsonBody = do - ra <- parseCheckJsonBody + ra <- iparseCheckJsonBody case ra of - J.Error s -> invalidArgs [pack s] - J.Success a -> return a + JT.IError path s -> invalidArgs [pack (JT.formatError path s)] + JT.ISuccess a -> return a -- | Convert a list of values to an 'J.Array'. array :: J.ToJSON a => [a] -> J.Value diff --git a/yesod-core/yesod-core.cabal b/yesod-core/yesod-core.cabal index 4aa6b021e..36bbd7fdb 100644 --- a/yesod-core/yesod-core.cabal +++ b/yesod-core/yesod-core.cabal @@ -1,5 +1,5 @@ name: yesod-core -version: 1.6.24.2 +version: 1.6.25 license: MIT license-file: LICENSE author: Michael Snoyman @@ -26,7 +26,7 @@ library hs-source-dirs: src build-depends: base >= 4.10 && < 5 - , aeson >= 1.0 + , aeson >= 2.1.0.0 , auto-update , blaze-html >= 0.5 , blaze-markup >= 0.7.1