@@ -21,7 +21,8 @@ import Data.Either (isRight)
21import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
22import qualified Data.List as L
22import qualified Data.List as L
23import Control.Exception.Base
23import Control.Exception.Base
24−import qualified Data.Text.IO as TIO
24+import qualified Data.ByteString as BS
25+import qualified Data.Text.Encoding as TE
25import Data.ByteString (ByteString)
26import Data.ByteString (ByteString)
26import Data.Monoid
27import Data.Monoid
27import qualified Crypto.Hash.SHA256 as SHA256
28import qualified Crypto.Hash.SHA256 as SHA256
@@ -200,7 +201,7 @@ writeGraphTransactionIdFile sync destDirectory (TransactionGraph _ transSet) = w
201readGraphTransactionIdFileDigest :: FilePath -> IO LockFileHash
202readGraphTransactionIdFileDigest :: FilePath -> IO LockFileHash
202readGraphTransactionIdFileDigest dbdir = do
203readGraphTransactionIdFileDigest dbdir = do
203− let graphTransactionIdData = TIO.readFile (transactionLogPath dbdir)
204+ let graphTransactionIdData = readUTF8FileOrError (transactionLogPath dbdir)
204 SHA256.hash . encodeUtf8 <$> graphTransactionIdData
205 SHA256.hash . encodeUtf8 <$> graphTransactionIdData
206readGraphTransactionIdFile :: FilePath -> IO (Either PersistenceError [(TransactionId, UTCTime, [TransactionId])])
207readGraphTransactionIdFile :: FilePath -> IO (Either PersistenceError [(TransactionId, UTCTime, [TransactionId])])
@@ -210,5 +211,15 @@ readGraphTransactionIdFile dbdir = do
210 (readUUID tid, readEpoch epochText, map readUUID parentIds)
211 (readUUID tid, readEpoch epochText, map readUUID parentIds)
211 readUUID uuidText = fromMaybe (error "failed to read uuid") (U.fromText uuidText)
212 readUUID uuidText = fromMaybe (error "failed to read uuid") (U.fromText uuidText)
212 readEpoch t = posixSecondsToUTCTime (realToFrac (either (error "failed to read epoch") fst (double t)))
213 readEpoch t = posixSecondsToUTCTime (realToFrac (either (error "failed to read epoch") fst (double t)))
213− Right . map grapher . T.lines <$> TIO.readFile (transactionLogPath dbdir)
214+ Right . map grapher . T.lines <$> readUTF8FileOrError (transactionLogPath dbdir)
216+--rationale- reading essential database files must fail hard
217+readUTF8FileOrError :: FilePath -> IO (T.Text)
218+readUTF8FileOrError pathIn = do
219+ eFileBytes <- try (BS.readFile pathIn) :: IO (Either IOError BS.ByteString)
221+ Left err -> error (show err)
223+ case TE.decodeUtf8' fileBytes of
224+ Left err -> error (show err)
225+ Right utf8Bytes -> pure utf8Bytes