@@ -10,16 +10,19 @@ module StackTest.Repl
10
10
, replGetLine
11
11
) where
12
12
13
+ import Control.Exception (SomeException , catch , displayException , finally )
13
14
import Control.Monad (unless , when )
14
15
import Control.Monad.IO.Class (liftIO )
15
16
import Data.Maybe (fromMaybe )
16
17
import GHC.Stack (HasCallStack )
18
+ import System.Directory (removeFile )
17
19
import System.Environment (lookupEnv )
18
- import System.Exit (ExitCode (.. ))
20
+ import System.Exit (ExitCode (.. ), exitFailure )
19
21
import System.IO
20
- ( BufferMode (NoBuffering , LineBuffering ), Handle
21
- , hClose , hGetChar , hGetLine , hPutStrLn , hSetBuffering
22
+ ( BufferMode (NoBuffering , LineBuffering ), Handle , IOMode ( ReadMode )
23
+ , hClose , hGetChar , hGetContents' , hGetLine , hPutStrLn , hSetBuffering
22
24
, openTempFile
25
+ , withFile
23
26
)
24
27
25
28
import Control.Monad.Trans (lift )
@@ -87,6 +90,18 @@ runRepl cmd args actions = do
87
90
88
91
-- run the test script which is to talk to the GHCi subprocess.
89
92
runReaderT actions (ReplConnection rStdin rStdout)
93
+ -- the nested actions script may fail in arbitrary ways; handle that here,
94
+ -- attaching the subprocess stderr as relevant context
95
+ `catch` \ (e :: SomeException ) -> do
96
+ putStrLn " =============================="
97
+ putStrLn " EXCEPTION in test: "
98
+ putStrLn . quote $ displayException e
99
+ putStrLn " ------[ stderr of repl ]------"
100
+ withFile stderrBufPath ReadMode $ \ h -> hGetContents' h >>= putStr . quote
101
+ putStrLn " =============================="
102
+ `finally` do
103
+ hClose stderrBufHandle
104
+ removeFile stderrBufPath
90
105
91
106
-- once done with the test, signal EOF on stdin for clean termination of ghci
92
107
hClose rStdin
@@ -104,5 +119,9 @@ repl :: HasCallStack => [String] -> Repl () -> IO ()
104
119
repl args action = do
105
120
stackExe' <- stackExe
106
121
ec <- runRepl stackExe' (" repl" : " --ghci-options=-ignore-dot-ghci" : args) action
107
- unless (ec == ExitSuccess ) $
108
- error $ " GHCi exited with " <> show ec
122
+ unless (ec == ExitSuccess ) $ do
123
+ putStrLn $ " repl exited with " <> show ec
124
+ exitFailure
125
+
126
+ quote :: String -> String
127
+ quote = unlines . map (" > " <> ) . lines
0 commit comments