Skip to content

bracket discards exception context #45

Description

@guibou

bracket (and similar functions) discards the ExceptionContext associated with an exception.

For example, the following code:

{-# LANGUAGE DeriveAnyClass #-}
import Control.Exception as BaseException
import Control.Exception.Annotation
import Control.Exception.Context
import GHC.Generics
import Control.Monad.Trans.Resource
import Control.Monad.Trans
import Control.Exception.Safe as SafeException

data Ann = Ann String
  deriving (Generic, ExceptionAnnotation, Show)

data Exc = Exc String
  deriving (Generic, Exception, Show)

main = do
      BaseException.bracket_ (pure ()) (pure ()) $ do
        annotateIO (Ann "I'm a nice annotation") $ BaseException.throwIO (Exc "failure!!")

When run, with ghc-9.12.2 and safe-exception-0.1.7.4 would result into:

$ runhaskell BracketExceptionHandling.hs 
BracketExceptionHandling.hs: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:

Exc "failure!!"

Ann "I'm a nice annotation"
HasCallStack backtrace:
  throwIO, called at BracketExceptionHandling.hs:18:52 in main:Main

However, replace BaseException.bracket_ by SafeException.bracket_ and you'll get:

runhaskell BracketExceptionHandling.hs
BracketExceptionHandling.hs: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:

Exc "failure!!"

While handling Exc "failure!!"

HasCallStack backtrace:
  bracket_, called at BracketExceptionHandling.hs:17:7 in main:Main

I was initially surprised by this behavior because my initial (and wrong) understanding is that bracket_ from safe-exceptions behaves the same as the one from base: it does not care about the fact that the exception is async or not, so I initially thought that it was a reexport.

However it behaves differently: it uses uninterruptibleMask.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions