diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-app-v1.20.1.0...main)
+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-app-v1.20.1.1...main)
 
+## [v1.20.1.1](https://github.com/freckle/freckle-app/compare/freckle-app-v1.20.1.0...freckle-app-v1.20.1.1)
+
+In `Freckle.App.Test.Yesod`, exceptions thrown by `getRawBody`, `getJsonBody`,
+and `getCsvBody` are now `HUnitFailure` (what you would normally expect when a
+test assertion fails) rather than `IOException`.
+
 ## [v1.20.1.0](https://github.com/freckle/freckle-app/compare/freckle-app-v1.20.0.1...freckle-app-v1.20.1.0)
 
 Modules moving between packages:
@@ -8,9 +14,9 @@
 - `Freckle.App.Exception(.*)` has moved to the `freckle-exception` package
 - All moved modules are re-exported from `freckle-app`.
 
-- Added `Freckle.App.Test.Hspec.AnnotatedException` (`unwrapAnnotatedHUnitFailure`).
-  It is recommended that all hspec test suites for packages that use `freckle-prelude`
-  add this spec hook.
+Added `Freckle.App.Test.Hspec.AnnotatedException` (`unwrapAnnotatedHUnitFailure`).
+It is recommended that all hspec test suites for packages that use `freckle-prelude`
+add this spec hook.
 
 ## [v1.20.0.1](https://github.com/freckle/freckle-app/compare/freckle-app-v1.20.0.0...freckle-app-v1.20.0.1)
 
diff --git a/freckle-app.cabal b/freckle-app.cabal
--- a/freckle-app.cabal
+++ b/freckle-app.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.22
 name:               freckle-app
-version:            1.20.1.0
+version:            1.20.1.1
 license:            MIT
 license-file:       LICENSE
 maintainer:         Freckle Education
diff --git a/library/Freckle/App/Test/Yesod.hs b/library/Freckle/App/Test/Yesod.hs
--- a/library/Freckle/App/Test/Yesod.hs
+++ b/library/Freckle/App/Test/Yesod.hs
@@ -89,9 +89,9 @@
 import Data.Csv (FromNamedRecord, decodeByName)
 import Data.Text qualified as T
 import Data.Vector qualified as V
+import Freckle.App.Test (expectationFailure)
 import Network.HTTP.Types.Header (hAccept, hAcceptLanguage, hContentType)
 import Network.Wai.Test (SResponse (..))
-import Test.Hspec.Expectations.Lifted (expectationFailure)
 import Web.Cookie (SetCookie)
 import Yesod.Core (RedirectUrl, Yesod)
 import Yesod.Test
@@ -159,22 +159,26 @@
 testSetCookie = liftYesodExample . Yesod.Test.testSetCookie
 
 -- | Get the body of the most recent response and decode it as JSON
-getJsonBody :: forall a m site. (MonadYesodExample site m, FromJSON a) => m a
+getJsonBody
+  :: forall a m site. (MonadYesodExample site m, FromJSON a, HasCallStack) => m a
 getJsonBody = either err pure . eitherDecode =<< getRawBody
  where
-  err e = throwString $ "Error decoding JSON response body: " <> e
+  err e = expectationFailure $ "Error decoding JSON response body: " <> e
 
 -- | Get the body of the most recent response and decode it as CSV
 getCsvBody
-  :: forall a m site. (MonadYesodExample site m, FromNamedRecord a) => m [a]
+  :: forall a m site
+   . (MonadYesodExample site m, FromNamedRecord a, HasCallStack)
+  => m [a]
 getCsvBody = either err (pure . V.toList . snd) . decodeByName =<< getRawBody
  where
-  err e = throwString $ "Error decoding CSV response body: " <> e
+  err e = expectationFailure $ "Error decoding CSV response body: " <> e
 
 -- | Get the body of the most recent response as a byte string
-getRawBody :: forall m site. MonadYesodExample site m => m BSL.ByteString
+getRawBody
+  :: forall m site. (MonadYesodExample site m, HasCallStack) => m BSL.ByteString
 getRawBody =
-  fmap simpleBody . maybe (throwString "Test response had no body") pure
+  fmap simpleBody . maybe (expectationFailure "Test response had no body") pure
     =<< getResponse
 
 -- | Get the most recently provided response value, if available
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: freckle-app
-version: 1.20.1.0
+version: 1.20.1.1
 maintainer: Freckle Education
 category: Utils
 github: freckle/freckle-app
