diff --git a/src/Data/Validity/Aeson.hs b/src/Data/Validity/Aeson.hs
--- a/src/Data/Validity/Aeson.hs
+++ b/src/Data/Validity/Aeson.hs
@@ -3,6 +3,7 @@
 module Data.Validity.Aeson where
 
 import Data.Aeson
+import Data.Aeson.Types
 import Data.Validity
 import Data.Validity.HashMap ()
 import Data.Validity.Scientific ()
@@ -17,3 +18,20 @@
     validate (Number s) = annotate s "Number"
     validate (Bool b) = annotate b "Bool"
     validate Null = valid
+
+-- | Modify a parser to fail on invalid results.
+parseJSONValid :: Validity a => Parser a -> Parser a
+parseJSONValid p = do
+  r <- p
+  case prettyValidate r of
+    Left err -> fail $ unwords ["Parsed value is not valid:", err]
+    Right r' -> pure r'
+
+-- | Modify a parsing function to fail on invalid results.
+--
+-- Easy to use with the `withX` helper functions:
+--
+-- > parseJSON = parseJSONValidwith . withObject "MyThing" $ \o ->
+-- >   MyThing <$> ...
+parseJSONValidWith :: Validity a => (value -> Parser a) -> (value -> Parser a)
+parseJSONValidWith func v = parseJSONValid $ func v
diff --git a/test/Data/Validity/AesonSpec.hs b/test/Data/Validity/AesonSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/Validity/AesonSpec.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Data.Validity.AesonSpec where
+
+import Data.Aeson
+import Data.Validity
+import Data.Validity.Aeson
+import GHC.Generics (Generic)
+import Test.Hspec
+
+data MyRatio = MyRatio Word Word
+  deriving (Show, Eq, Generic)
+
+instance Validity MyRatio where
+  validate mr@(MyRatio _ d) = mconcat [genericValidate mr, declare "The denominator is not zero" $ d /= 0]
+
+instance FromJSON MyRatio where
+  parseJSON = parseJSONValidWith . withObject "MyRatio" $ \o ->
+    MyRatio <$> o .: "numerator" <*> o .: "denominator"
+
+spec :: Spec
+spec =
+  describe "parseJSONValid" $ do
+    it "does not allow this invalid ratio to be parsed" $
+      case fromJSON (object ["numerator" .= (1 :: Word), "denominator" .= (0 :: Word)]) of
+        Error _ -> pure ()
+        Success (MyRatio _ _) -> expectationFailure "Should have failed."
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
diff --git a/validity-aeson.cabal b/validity-aeson.cabal
--- a/validity-aeson.cabal
+++ b/validity-aeson.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 901d85e4c2b8241e9a335531514b9be204b784fc956f6013b41ad6b41ff87e5e
+-- hash: 2c831f84f06bf64abf7f2d9df6acbdbef462d918f20615688f51d89683e57cae
 
 name:           validity-aeson
-version:        0.2.0.3
+version:        0.2.0.4
 synopsis:       Validity instances for aeson
 category:       Validity
 homepage:       https://github.com/NorfairKing/validity#readme
@@ -38,4 +38,21 @@
     , validity-text >=0.3
     , validity-unordered-containers >=0.1
     , validity-vector >=0.1
+  default-language: Haskell2010
+
+test-suite validity-aeson-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Data.Validity.AesonSpec
+      Paths_validity_aeson
+  hs-source-dirs:
+      test/
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:
+      aeson
+    , base >=4.7 && <5
+    , hspec
+    , validity
+    , validity-aeson
   default-language: Haskell2010
