@@ -23,11 +23,12 @@ import Data.Maybe
2323
2424import Prelude hiding (catch )
2525#if MIN_VERSION_base(4,21,0)
26- import Control.Exception.Annotation ( ExceptionAnnotation ( .. ))
27- import Control.Exception.Context ( displayExceptionContext , getExceptionAnnotations )
28- import Control.Exception.Backtrace ( Backtraces , displayBacktraces )
26+ import Control.Exception.Annotation
27+ import Control.Exception.Context
28+ import Control.Exception.Backtrace
2929#endif
3030import GHC.Stack (HasCallStack )
31+ import Debug.Trace
3132
3233main = defaultMain tests
3334
@@ -631,7 +632,39 @@ exception_rethrow = [
631632 wait a,
632633 testCase " withAsync inside" $ compareTwoExceptions $ \ action -> do
633634 withAsync doForever $ \ a -> do
634- action
635+ action,
636+
637+ testCase " withAsync does not wrap with WhileHandling and contain an asyncWaitLocation" $ do
638+ -- This test is fragile. It checks that when calling `wait` on an async,
639+ -- we end up with at least two interesting annotations: the backtrace
640+ -- which shows the localisation of the exception thrown in the async, and
641+ -- an AsyncWaitLocation which shows the location of the wait call.
642+ --
643+ -- It also checks that no other annotation are provided (for example, a
644+ -- "WhileHandling")
645+ --
646+ -- However, this can change in future GHC version, for example, new
647+ -- annotations may be added, or Backtraces may change its type / name.
648+ -- Also, depending on the build configuration, maybe there will have
649+ -- other backtraces (such as DWARF or IPE, ...)
650+ e <- tryWithContext $ do
651+ withAsync (throwIO Exc ) $ \ async -> do
652+ wait async
653+ case e of
654+ Right () -> fail " should have raised an exception"
655+ Left (ExceptionWithContext (ExceptionContext annotations) Exc ) -> do
656+ assertEqual " Only two annotations" (length annotations) 2
657+ assertBool " Has AsyncWaitLocation annotation" (any isAsyncWaitLocation annotations)
658+ assertBool " Has Backtraces annotation" (any isBacktraces annotations)
635659 ]
660+
661+ isAsyncWaitLocation (SomeExceptionAnnotation ann) = case cast ann of
662+ Just (AsyncWaitLocation _) -> True
663+ _ -> traceShow (typeOf ann) False
664+
665+ isBacktraces (SomeExceptionAnnotation ann) = case cast ann of
666+ Just (_ :: Backtraces ) -> True
667+ _ -> False
668+
636669#endif
637670
0 commit comments