module Unison.Util.Exception where

import Control.Concurrent.Async (waitCatch, withAsync)
import Unison.Prelude

-- These are adapted from: https://github.com/snoyberg/classy-prelude/blob/ccd19f2c62882c69d5dcdd3da5c0df1031334c5a/classy-prelude/ClassyPrelude.hs#L320
-- License is MIT: https://github.com/snoyberg/classy-prelude/blob/ccd19f2c62882c69d5dcdd3da5c0df1031334c5a/classy-prelude/LICENSE

-- Catch all exceptions except asynchronous exceptions.
tryAny :: (MonadIO m) => IO a -> m (Either SomeException a)
tryAny :: forall (m :: * -> *) a.
MonadIO m =>
IO a -> m (Either SomeException a)
tryAny IO a
action = IO (Either SomeException a) -> m (Either SomeException a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either SomeException a) -> m (Either SomeException a))
-> IO (Either SomeException a) -> m (Either SomeException a)
forall a b. (a -> b) -> a -> b
$ IO a
-> (Async a -> IO (Either SomeException a))
-> IO (Either SomeException a)
forall a b. IO a -> (Async a -> IO b) -> IO b
withAsync IO a
action Async a -> IO (Either SomeException a)
forall a. Async a -> IO (Either SomeException a)
waitCatch

-- Catch all exceptions except asynchronous exceptions.
catchAny :: IO a -> (SomeException -> IO a) -> IO a
catchAny :: forall a. IO a -> (SomeException -> IO a) -> IO a
catchAny IO a
action SomeException -> IO a
onE = IO a -> IO (Either SomeException a)
forall (m :: * -> *) a.
MonadIO m =>
IO a -> m (Either SomeException a)
tryAny IO a
action IO (Either SomeException a)
-> (Either SomeException a -> IO a) -> IO a
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (SomeException -> IO a)
-> (a -> IO a) -> Either SomeException a -> IO a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SomeException -> IO a
onE a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return