@@ -119,6 +119,8 @@ module System.Process.Typed
119119
120120 -- * Exceptions
121121 , ExitCodeException (.. )
122+ , exitCodeExceptionWithOutput
123+ , exitCodeExceptionNoOutput
122124 , ByteStringOutputException (.. )
123125
124126 -- * Re-exports
@@ -638,12 +640,7 @@ checkExitCodeSTM p = do
638640 ec <- readTMVar (pExitCode p)
639641 case ec of
640642 ExitSuccess -> return ()
641- _ -> throwSTM ExitCodeException
642- { eceExitCode = ec
643- , eceProcessConfig = clearStreams (pConfig p)
644- , eceStdout = L. empty
645- , eceStderr = L. empty
646- }
643+ _ -> throwSTM $ exitCodeExceptionNoOutput p ec
647644
648645-- | Returns the PID (process ID) of a subprocess.
649646--
@@ -682,6 +679,18 @@ getStdout = pStdout
682679getStderr :: Process stdin stdout stderr -> stderr
683680getStderr = pStderr
684681
682+ -- | Get a process's configuration.
683+ --
684+ -- This is useful for constructing 'ExitCodeException's.
685+ --
686+ -- Note that the stdin, stdout, and stderr streams are stored in the 'Process',
687+ -- not the 'ProcessConfig', so the returned 'ProcessConfig' will always have
688+ -- empty stdin, stdout, and stderr values.
689+ --
690+ -- @since 0.2.12.0
691+ getProcessConfig :: Process stdin stdout stderr -> ProcessConfig () () ()
692+ getProcessConfig = pConfig
693+
685694-- | Take 'System.Process.ProcessHandle' out of the 'Process'.
686695-- This method is needed in cases one need to use low level functions
687696-- from the @process@ package. Use cases for this method are:
@@ -703,3 +712,45 @@ getStderr = pStderr
703712-- @since 0.1.1
704713unsafeProcessHandle :: Process stdin stdout stderr -> P. ProcessHandle
705714unsafeProcessHandle = pHandle
715+
716+ -- | Get an 'ExitCodeException' containing the process's stdout and stderr data.
717+ --
718+ -- Note that this will call 'waitExitCode' to block until the process exits, if
719+ -- it has not exited already.
720+ --
721+ -- Unlike 'checkExitCode' and similar, this will return an 'ExitCodeException'
722+ -- even if the process exits with 'ExitSuccess'.
723+ --
724+ -- @since 0.2.12.0
725+ exitCodeExceptionWithOutput :: MonadIO m
726+ => Process stdin (STM L. ByteString ) (STM L. ByteString )
727+ -> m ExitCodeException
728+ exitCodeExceptionWithOutput process = liftIO $ atomically $ do
729+ exitCode <- waitExitCodeSTM process
730+ stdout <- getStdout process
731+ stderr <- getStderr process
732+ pure ExitCodeException
733+ { eceExitCode = exitCode
734+ , eceProcessConfig = pConfig process
735+ , eceStdout = stdout
736+ , eceStderr = stderr
737+ }
738+
739+ -- | Get an 'ExitCodeException' containing no data other than the exit code and
740+ -- process config.
741+ --
742+ -- Unlike 'checkExitCode' and similar, this will return an 'ExitCodeException'
743+ -- even if the process exits with 'ExitSuccess'.
744+ --
745+ -- @since 0.2.12.0
746+ exitCodeExceptionNoOutput :: Process stdin stdout stderr
747+ -> ExitCode
748+ -> ExitCodeException
749+ exitCodeExceptionNoOutput process exitCode =
750+ ExitCodeException
751+ { eceExitCode = exitCode
752+ , eceProcessConfig = pConfig process
753+ , eceStdout = L. empty
754+ , eceStderr = L. empty
755+ }
756+
0 commit comments