@@ -101,8 +101,6 @@ import Reflex.NotReady.Class
101101import Reflex.Patch
102102import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
103103
104−
105−
106104#ifdef DEBUG_TRACE_EVENTS
107105import qualified Data.ByteString.Char8 as BS8
108106import System.IO (stderr)
@@ -1322,12 +1320,17 @@ traceM _ _ = return ()
13221320#endif
13231321
13241322
1325−
1326−
13271323whoCreatedIORef :: IORef a -> IO [String]
13281324whoCreatedIORef (IORef a) = whoCreated $! a
13291325
13301326#ifdef DEBUG_CYCLES
1327+
1328+data EventLoopException = EventLoopException (Forest String)
1329+instance Exception EventLoopException
1330+
1331+instance Show EventLoopException where
1332+ show (EventLoopException stacks) = "Causality loop detected:\n" <> drawForest stacks
1333+
13311334groupByHead :: Eq a => [NonEmpty a] -> [(a, NonEmpty [a])]
13321335groupByHead = \case
13331336 [] -> []
@@ -1339,8 +1342,19 @@ groupByHead = \case
13391342
13401343listsToForest :: Eq a => [[a]] -> Forest a
13411344listsToForest l = fmap (\(a, l') -> Node a $ listsToForest $ toList l') $ groupByHead $ catMaybes $ fmap nonEmpty l
1345+
1346+#else
1347+
1348+data EventLoopException = EventLoopException
1349+instance Exception EventLoopException
1350+
1351+instance Show EventLoopException where
1352+ show EventLoopException = "Causality loop detected: \n" <>
1353+ "no location information, compile with --enable-profiling and reflex with flag 'debug-cycles'"
1354+
13421355#endif
13431356
1357+
13441358{-# INLINE propagateSubscriberHold #-}
13451359propagateSubscriberHold :: forall x p. (HasSpiderTimeline x, Patch p) => Hold x p -> p -> EventM x ()
13461360propagateSubscriberHold h a = do
@@ -1871,11 +1885,11 @@ checkCycle height = do
18711885#ifdef DEBUG_CYCLES
18721886 nodesInvolvedInCycle <- walkInvalidHeightParents $ eventSubscribedMerge subscribed
18731887 stacks <- forM nodesInvolvedInCycle $ \(Some es) -> whoCreatedEventSubscribed es
1874− let cycleInfo = ":\n" <> drawForest (listsToForest stacks)
1888+ throwIO (EventLoopException stacks)
18751889#else
1876− let cycleInfo = ""
1890+ throwIO EventLoopException
18771891#endif
1878− error $ "Causality loop found" <> cycleInfo
1892+
18791893
18801894mergeSubscriber :: forall x k v s a. (HasSpiderTimeline x, GCompare k) => Merge x k v s -> EventM x (k a) -> Subscriber x (v a)
18811895mergeSubscriber m getKey = Subscriber