snoyberg / mono-traversable

Type classes for mapping, folding, and traversing monomorphic containers
153 stars 63 forks source link

Catching custom async exceptions #109

Closed gbrsales closed 7 years ago

gbrsales commented 7 years ago

I'm using classy-prelude-conduit from lts-7.0.

I would expect the two functions prelude and classyPrelude in the following code to behave the same, but the second one (classyPrelude) is not catching the exception. Is this OK?

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE NoImplicitPrelude  #-}
{-# LANGUAGE OverloadedStrings  #-}

import           ClassyPrelude.Conduit hiding (yield)
import           Control.Concurrent    (forkIO, yield)
import qualified Control.Exception     as E
import           Control.Monad
import           Data.Typeable

data CustomAsync = CustomAsync
  deriving (Eq, Show, Typeable)

instance Exception CustomAsync

main :: IO ()
main = do
  prelude
  classyPrelude

prelude :: IO ()
prelude = do
  putStrLn "Prelude functions"
  self <- myThreadId
  E.handle (\CustomAsync -> putStrLn "received CustomAsync") $ do
    _ <- forkIO (E.throwTo self CustomAsync)
    forever yield

classyPrelude :: IO ()
classyPrelude = do
  putStrLn "ClassyPrelude functions"
  self <- myThreadId
  handleAsync (\CustomAsync -> putStrLn "received CustomAsync") $ do
    _ <- forkIO (throwTo self CustomAsync)
    forever yield
snoyberg commented 7 years ago

This is intentional behavior, please see the documentation for the safe-exceptions package:

https://haskell-lang.org/library/safe-exceptions

gbrsales commented 7 years ago

OK, now I understand why handleAsync was not catching CustomAsync. For that to work I needed to turn that exception into a child of SomeAsyncException, like this:

instance Exception CustomAsync where

  toException = toException . SomeAsyncException

  fromException x = do
    SomeAsyncException a <- fromException x
    cast a

Maybe you could extend the catchAsync haddock documentation with a direct link to https://github.com/fpco/safe-exceptions#determining-sync-vs-async. That section was really helpful in explaining what was going on.

snoyberg commented 7 years ago

Seems like a good change, mind sending a PR?

On Sun, Sep 25, 2016, 7:56 PM gbrsales notifications@github.com wrote:

OK, now I understand why handleAsync was not catching CustomAsync. For that to work I needed to turn that exception into a child of SomeAsyncException, like this:

instance Exception CustomAsync where

toException = toException . SomeAsyncException

fromException x = do SomeAsyncException a <- fromException x cast a

Maybe you could extend the catchAsync haddock documentation with a direct link to https://github.com/fpco/safe-exceptions#determining-sync-vs-async http://url. That section was really helpful in explaining what was going on.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/snoyberg/mono-traversable/issues/109#issuecomment-249432722, or mute the thread https://github.com/notifications/unsubscribe-auth/AADBBwBtTs1wUcXNpznEw0jU04hETiTrks5qtqe5gaJpZM4KEKyr .