Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions effectful-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# effectful-core-2.6.0.0 (????-??-??)
* Add `withException` to `Effectful.Exception`, similar to safe-exceptions and unliftio.
* **Breaking changes**:
- Change the order of type parameters in `raise` for better usability.
- `Effectful.Error.Static.ErrorWrapper` is no longer caught by `catchSync`.
Expand Down
16 changes: 16 additions & 0 deletions effectful-core/src/Effectful/Exception.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module Effectful.Exception
, C.ExitCase(..)
, finally
, onException
, withException

-- * Utils

Expand Down Expand Up @@ -512,6 +513,21 @@ onException
onException action handler = reallyUnsafeUnliftIO $ \unlift -> do
E.onException (unlift action) (unlift handler)

-- | Like 'onException', but provides the handler the thrown exception.
withException :: C.Exception e => Eff es a -> (e -> Eff es b) -> Eff es a
withException thing after = uninterruptibleMask $ \restore -> do
res1 <- try $ restore thing
case res1 of
Left e1 -> do
-- explicitly ignore exceptions from after. We know that
-- no async exceptions were thrown there, so therefore
-- the stronger exception must come from thing
--
-- https://github.com/fpco/safe-exceptions/issues/2
_ :: Either C.SomeException b <- try $ after e1
throwIO e1
Right x -> pure x

----------------------------------------
-- Utils

Expand Down
Loading