diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.1.4.0
+
+* Add `catchJust`, `handleJust`, and `tryJust`
+
 ## 0.1.3.0
 
 * Add `catchIO`, `handleIO`, and `tryIO`
diff --git a/safe-exceptions.cabal b/safe-exceptions.cabal
--- a/safe-exceptions.cabal
+++ b/safe-exceptions.cabal
@@ -1,5 +1,5 @@
 name:                safe-exceptions
-version:             0.1.3.0
+version:             0.1.4.0
 synopsis:            Safe, consistent, and easy exception handling
 description:         Please see README.md
 homepage:            https://github.com/fpco/safe-exceptions#readme
diff --git a/src/Control/Exception/Safe.hs b/src/Control/Exception/Safe.hs
--- a/src/Control/Exception/Safe.hs
+++ b/src/Control/Exception/Safe.hs
@@ -22,6 +22,7 @@
     , catchDeep
     , catchAnyDeep
     , catchAsync
+    , catchJust
 
     , handle
     , handleIO
@@ -29,6 +30,7 @@
     , handleDeep
     , handleAnyDeep
     , handleAsync
+    , handleJust
 
     , try
     , tryIO
@@ -36,6 +38,7 @@
     , tryDeep
     , tryAnyDeep
     , tryAsync
+    , tryJust
 
     , Handler(..)
     , catches
@@ -179,6 +182,14 @@
 catchAsync :: (C.MonadCatch m, Exception e) => m a -> (e -> m a) -> m a
 catchAsync = C.catch
 
+-- | 'catchJust' is like 'catch' but it takes an extra argument which
+-- is an exception predicate, a function which selects which type of
+-- exceptions we're interested in.
+--
+-- @since 0.1.4.0
+catchJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
+catchJust f a b = a `catch` \e -> maybe (throwM e) b $ f e
+
 -- | Flipped version of 'catch'
 --
 -- @since 0.1.0.0
@@ -220,6 +231,12 @@
 handleAsync :: (C.MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
 handleAsync = C.handle
 
+-- | Flipped 'catchJust'.
+--
+-- @since 0.1.4.0
+handleJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
+handleJust f = flip (catchJust f)
+
 -- | Same as upstream 'C.try', but will not catch asynchronous
 -- exceptions
 --
@@ -261,6 +278,13 @@
 -- @since 0.1.0.0
 tryAsync :: (C.MonadCatch m, E.Exception e) => m a -> m (Either e a)
 tryAsync = C.try
+
+-- | A variant of 'try' that takes an exception predicate to select
+-- which exceptions are caught.
+--
+-- @since 0.1.4.0
+tryJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
+tryJust f a = catch (Right `liftM` a) (\e -> maybe (throwM e) (return . Left) (f e))
 
 -- | Async safe version of 'E.onException'
 --
diff --git a/test/Control/Exception/SafeSpec.hs b/test/Control/Exception/SafeSpec.hs
--- a/test/Control/Exception/SafeSpec.hs
+++ b/test/Control/Exception/SafeSpec.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 module Control.Exception.SafeSpec (spec) where
 
@@ -6,11 +7,16 @@
 import qualified Control.Exception as E
 import Control.Exception.Safe
 import Control.Monad (forever)
+import Data.Typeable (Typeable)
 import Data.Void (Void, absurd)
 import System.IO.Unsafe (unsafePerformIO)
 import System.Timeout (timeout)
 import Test.Hspec
 
+newtype ExceptionPred = ExceptionPred { getExceptionPred :: Maybe () } deriving (Show, Eq, Typeable)
+
+instance Exception ExceptionPred
+
 -- | Ugly hack needed because the underlying type is not exported
 timeoutException :: SomeException
 timeoutException =
@@ -108,3 +114,13 @@
         describe "catchesDeep" $ withAll $ \e _ -> do
             res <- return (impureThrow e) `catchesDeep` [Handler (\(_ :: SomeException) -> return ())]
             res `shouldBe` ()
+
+    describe "catchJust" $ do
+      it "catches a selected exception" $ do
+        res <- catchJust getExceptionPred (throw (ExceptionPred (Just ()))) (return . Just)
+        res `shouldBe` Just ()
+
+      it "re-raises a selection that is passed on" $ do
+        let ex = ExceptionPred Nothing
+        res <- try (catchJust getExceptionPred (throw ex) (return . Just))
+        res `shouldBe` Left ex
