diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.2.2.0
+
+* Add `pureTry` and `pureTryDeep`
+
 ## 0.2.1.0
 
 * Add `UnliftIO.STM`
diff --git a/src/UnliftIO/Exception.hs b/src/UnliftIO/Exception.hs
--- a/src/UnliftIO/Exception.hs
+++ b/src/UnliftIO/Exception.hs
@@ -38,6 +38,8 @@
   , tryDeep
   , tryAnyDeep
   , tryJust
+  , pureTry
+  , pureTryDeep
 
   , Handler(..)
   , catches
@@ -88,6 +90,7 @@
 import qualified Control.Exception as EUnsafe
 import Control.DeepSeq (NFData (..), ($!!))
 import Data.Typeable (Typeable, cast)
+import System.IO.Unsafe (unsafePerformIO)
 
 #if MIN_VERSION_base(4,9,0)
 import GHC.Stack (prettySrcLoc)
@@ -212,6 +215,21 @@
 -- @since 0.1.0.0
 tryJust :: (MonadUnliftIO m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
 tryJust f a = catch (Right `liftM` a) (\e -> maybe (throwIO e) (return . Left) (f e))
+
+-- | Evaluate the value to WHNF and catch any synchronous exceptions.
+--
+-- The expression may still have bottom values within it; you may
+-- instead want to use 'pureTryDeep'.
+--
+-- @since 0.2.2.0
+pureTry :: a -> Either SomeException a
+pureTry a = unsafePerformIO $ (return $! Right $! a) `catchAny` (return . Left)
+
+-- | Evaluate the value to NF and catch any synchronous exceptions.
+--
+-- @since 0.2.2.0
+pureTryDeep :: NFData a => a -> Either SomeException a
+pureTryDeep = unsafePerformIO . tryAnyDeep . return
 
 -- | Generalized version of 'EUnsafe.Handler'.
 --
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/test/UnliftIO/ExceptionSpec.hs b/test/UnliftIO/ExceptionSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/UnliftIO/ExceptionSpec.hs
@@ -0,0 +1,17 @@
+module UnliftIO.ExceptionSpec (spec) where
+
+import Test.Hspec
+import UnliftIO
+
+spec :: Spec
+spec = do
+  let shouldLeft x = either (const Nothing) Just x `shouldBe` Nothing
+      shouldRight x = either (Just . show) (const Nothing) x `shouldBe` Nothing
+  describe "pureTry" $ do
+    it "Right for defined values" $ shouldRight $ pureTry ()
+    it "Left for bottom" $ shouldLeft $ pureTry (undefined :: ())
+    it "Right for wrapped bottom" $ shouldRight $ pureTry $ Just (undefined :: ())
+  describe "pureTryDeep" $ do
+    it "Right for defined values" $ shouldRight $ pureTryDeep ()
+    it "Left for bottom" $ shouldLeft $ pureTryDeep (undefined :: ())
+    it "Left for wrapped bottom" $ shouldLeft $ pureTryDeep $ Just (undefined :: ())
diff --git a/unliftio.cabal b/unliftio.cabal
--- a/unliftio.cabal
+++ b/unliftio.cabal
@@ -2,12 +2,12 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 3d617105f39ba722d85acf902a79e88a36deefc409b7655ae9d69526e65b648f
+-- hash: 5a724f566f49e39a6208566cbc3e42117113cd8c19867e2f53151c8022d9919b
 
 name:           unliftio
-version:        0.2.1.0
+version:        0.2.2.0
 synopsis:       The MonadUnliftIO typeclass for unlifting monads to IO (batteries included)
-description:    Please see the README.md file for details.
+description:    Please see the documentation and README at <https://www.stackage.org/package/unliftio>
 category:       Control
 homepage:       https://github.com/fpco/unliftio/tree/master/unliftio#readme
 author:         Michael Snoyman, Francesco Mazzoli
@@ -50,5 +50,29 @@
       UnliftIO.Temporary
       UnliftIO.Timeout
   other-modules:
+      Paths_unliftio
+  default-language: Haskell2010
+
+test-suite unliftio-spec
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  hs-source-dirs:
+      test
+  build-depends:
+      async >2.1.1
+    , base >=4.7 && <5
+    , deepseq
+    , directory
+    , filepath
+    , hspec
+    , stm >=2.4.3
+    , transformers
+    , unliftio
+    , unliftio-core
+  if !os(Windows)
+    build-depends:
+        unix
+  other-modules:
+      UnliftIO.ExceptionSpec
       Paths_unliftio
   default-language: Haskell2010
