From b99e4504d42413a0695f38a4189d850ef9db9204 Mon Sep 17 00:00:00 2001 From: Tom Ellis Date: Tue, 8 Apr 2025 20:19:41 +0100 Subject: [PATCH 1/2] Pull out unpack --- src/System/Process/Typed/Internal.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/System/Process/Typed/Internal.hs b/src/System/Process/Typed/Internal.hs index 18942e1..01d5fc6 100644 --- a/src/System/Process/Typed/Internal.hs +++ b/src/System/Process/Typed/Internal.hs @@ -620,11 +620,13 @@ instance Show ExitCodeException where , show (eceProcessConfig ece) { pcEnv = Nothing } , if L.null (eceStdout ece) then "" - else "Standard output:\n\n" ++ L8.unpack (eceStdout ece) + else "Standard output:\n\n" ++ unpack (eceStdout ece) , if L.null (eceStderr ece) then "" - else "Standard error:\n\n" ++ L8.unpack (eceStderr ece) + else "Standard error:\n\n" ++ unpack (eceStderr ece) ] + where + unpack = L8.unpack -- | Wrapper for when an exception is thrown when reading from a child -- process, used by 'byteStringOutput'. From 45af1e8bd9a03436154e0d738d772614fe83e93d Mon Sep 17 00:00:00 2001 From: Tom Ellis Date: Tue, 8 Apr 2025 20:19:44 +0100 Subject: [PATCH 2/2] Format ExitCodeException stdout and stderr with UTF-8 Closes https://github.com/fpco/typed-process/issues/86 Thanks to @9999years for the legwork on this change --- ChangeLog.md | 4 ++++ package.yaml | 1 + src/System/Process/Typed/Internal.hs | 8 ++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 95a6483..551a20d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,9 @@ # ChangeLog for typed-process +* Format stdout and stderr in `ExitCodeException` assuming they are in + UTF-8. See [#87](https://github.com/fpco/typed-process/pull/87). + Thanks to @9999years for the legwork on this change. + ## 0.2.12.0 * Add `getPid`, `exitCodeExceptionWithOutput`, diff --git a/package.yaml b/package.yaml index 0339e8a..311cafa 100644 --- a/package.yaml +++ b/package.yaml @@ -19,6 +19,7 @@ dependencies: - bytestring - process >=1.2 - stm +- text - transformers - unliftio-core diff --git a/src/System/Process/Typed/Internal.hs b/src/System/Process/Typed/Internal.hs index 01d5fc6..a5ee0d1 100644 --- a/src/System/Process/Typed/Internal.hs +++ b/src/System/Process/Typed/Internal.hs @@ -23,9 +23,11 @@ import Control.Concurrent.Async (async) import Control.Concurrent.STM (newEmptyTMVarIO, atomically, putTMVar, readTMVar, STM, tryPutTMVar, throwSTM) import System.Exit (ExitCode) import qualified Data.ByteString.Lazy as L -import qualified Data.ByteString.Lazy.Char8 as L8 import Data.String (IsString (fromString)) import Control.Monad.IO.Unlift +import qualified Data.Text.Encoding.Error as TEE +import qualified Data.Text.Lazy as TL +import qualified Data.Text.Lazy.Encoding as TLE #if MIN_VERSION_process(1, 4, 0) && !WINDOWS import System.Posix.Types (GroupID, UserID) @@ -626,7 +628,9 @@ instance Show ExitCodeException where else "Standard error:\n\n" ++ unpack (eceStderr ece) ] where - unpack = L8.unpack + -- Format with UTF-8, because we have to choose some encoding, + -- and UTF-8 is the least likely to be wrong in general. + unpack = TL.unpack . TLE.decodeUtf8With TEE.lenientDecode -- | Wrapper for when an exception is thrown when reading from a child -- process, used by 'byteStringOutput'.