Skip to content

Commit 206e7c2

Browse files
committed
Eliminate a corner case of losing exception messages
1 parent d062347 commit 206e7c2

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Changelog for Shake (* = breaking change)
22

3+
Eliminate a corner case of losing exception messages
34
Make FSATrace available as a result type
45
Commands which have AutoDeps aren't also linted
56
#278, add StdoutTrim - like Stdout, but with trim applied

src/Development/Shake/Internal/Core/Monad.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@ type Capture a = (a -> IO ()) -> IO ()
6969
runRAW :: ro -> rw -> RAW ro rw a -> Capture (Either SomeException a)
7070
runRAW ro rw m k = do
7171
rw <- newIORef rw
72-
handler <- newIORef undefined
72+
handler <- newIORef throwIO
7373
writeIORef handler $ \e -> do
7474
-- make sure we never call the error continuation twice
7575
writeIORef handler throwIO
7676
k $ Left e
77-
goRAW handler ro rw m (k . Right)
77+
-- If the continuation itself throws an error we need to make sure we
78+
-- don't end up running it twice (once with its result, once with its own exception)
79+
goRAW handler ro rw m (\v -> do writeIORef handler throwIO; k $ Right v)
7880
`catch_` \e -> ($ e) =<< readIORef handler
7981

8082
goRAW :: forall ro rw a . IORef (SomeException -> IO ()) -> ro -> IORef rw -> RAW ro rw a -> Capture a

src/Test/Monad.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,11 @@ main = testSimple $ do
8989
k $ Left $ toException Overflow
9090
flip catchRAW (const $ liftIO $ modifyIORef ref ('y':)) $ throwRAW $ toException Overflow
9191
(===) "xyxyy" =<< readIORef ref
92+
93+
-- what if we throw an exception inside the continuation of run
94+
ref <- newIORef 0
95+
res <- try $ runRAW 1 "test" (return 1) $ \_ -> do
96+
modifyIORef ref (+1)
97+
throwIO Overflow
98+
res === Left Overflow
99+
(=== 1) =<< readIORef ref

0 commit comments

Comments
 (0)