;check: accounts, commodities, payees, ordereddates: improve errors
Error messages for these four are now a bit fancier and more consistent. But not yet optimised for machine readability. Cf #1436. Added to hledger-lib: chomp1, linesPrepend[2].
This commit is contained in:
		
							parent
							
								
									e59603a04a
								
							
						
					
					
						commit
						31ea37a785
					
				| @ -14,8 +14,17 @@ | |||||||
| ;   salary | ;   salary | ||||||
| ; liabilities | ; liabilities | ||||||
| ;   debts | ;   debts | ||||||
|  | account assets:bank:checking | ||||||
|  | account income:salary | ||||||
|  | account income:gifts | ||||||
|  | account assets:bank:saving | ||||||
|  | account assets:cash | ||||||
|  | account expenses:food | ||||||
|  | account expenses:supplies | ||||||
|  | account liabilities:debts | ||||||
|  | commodity $ | ||||||
| 
 | 
 | ||||||
| 2008/01/01 income | 2018/01/01 income | ||||||
|     assets:bank:checking  $1 |     assets:bank:checking  $1 | ||||||
|     income:salary |     income:salary | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -150,6 +150,7 @@ import Text.Megaparsec.Custom | |||||||
| import Hledger.Data | import Hledger.Data | ||||||
| import Hledger.Utils | import Hledger.Utils | ||||||
| import Safe (headMay) | import Safe (headMay) | ||||||
|  | import Text.Printf (printf) | ||||||
| 
 | 
 | ||||||
| --- ** doctest setup | --- ** doctest setup | ||||||
| -- $setup | -- $setup | ||||||
| @ -376,9 +377,11 @@ journalCheckPayeesDeclared j = sequence_ $ map checkpayee $ jtxns j | |||||||
|   where |   where | ||||||
|     checkpayee t |     checkpayee t | ||||||
|       | p `elem` ps = Right () |       | p `elem` ps = Right () | ||||||
|       | otherwise          = |       | otherwise = Left $  | ||||||
|           Left $ "undeclared payee \""++T.unpack p++"\"" |           printf "undeclared payee \"%s\"\nat: %s\n\n%s" | ||||||
|             ++ "\nin transaction at: "++showGenericSourcePos (tsourcepos t) |             (T.unpack p)  | ||||||
|  |             (showGenericSourcePos $ tsourcepos t) | ||||||
|  |             (linesPrepend2 "> " "  " $ chomp1 $ showTransaction t) | ||||||
|       where |       where | ||||||
|         p  = transactionPayee t |         p  = transactionPayee t | ||||||
|         ps = journalPayeesDeclared j |         ps = journalPayeesDeclared j | ||||||
| @ -390,11 +393,13 @@ journalCheckAccountsDeclared j = sequence_ $ map checkacct $ journalPostings j | |||||||
|   where |   where | ||||||
|     checkacct Posting{paccount,ptransaction} |     checkacct Posting{paccount,ptransaction} | ||||||
|       | paccount `elem` as = Right () |       | paccount `elem` as = Right () | ||||||
|       | otherwise          =  |       | otherwise = Left $ | ||||||
|           Left $ "undeclared account \""++T.unpack paccount++"\"" |           (printf "undeclared account \"%s\"\n" (T.unpack paccount)) | ||||||
|             ++ case ptransaction of |           ++ case ptransaction of  | ||||||
|                 Just Transaction{tsourcepos} -> "\nin transaction at: "++showGenericSourcePos tsourcepos |               Nothing -> "" | ||||||
|                 Nothing -> "" |               Just t  -> printf "in transaction at: %s\n\n%s" | ||||||
|  |                           (showGenericSourcePos $ tsourcepos t) | ||||||
|  |                           (linesPrepend "  " $ chomp1 $ showTransaction t) | ||||||
|       where |       where | ||||||
|         as = journalAccountNamesDeclared j |         as = journalAccountNamesDeclared j | ||||||
| 
 | 
 | ||||||
| @ -407,10 +412,13 @@ journalCheckCommoditiesDeclared j = | |||||||
|     checkcommodities Posting{..} = |     checkcommodities Posting{..} = | ||||||
|       case mfirstundeclaredcomm of |       case mfirstundeclaredcomm of | ||||||
|         Nothing -> Right () |         Nothing -> Right () | ||||||
|         Just c  -> Left $ "undeclared commodity \""++T.unpack c++"\"" |         Just c  -> Left $ | ||||||
|  |           (printf "undeclared commodity \"%s\"\n" (T.unpack c)) | ||||||
|           ++ case ptransaction of  |           ++ case ptransaction of  | ||||||
|                 Just Transaction{tsourcepos} -> "\nin transaction at: "++showGenericSourcePos tsourcepos |               Nothing -> "" | ||||||
|                 Nothing -> ""       |               Just t  -> printf "in transaction at: %s\n\n%s" | ||||||
|  |                           (showGenericSourcePos $ tsourcepos t) | ||||||
|  |                           (linesPrepend "  " $ chomp1 $ showTransaction t) | ||||||
|       where |       where | ||||||
|         mfirstundeclaredcomm =  |         mfirstundeclaredcomm =  | ||||||
|           headMay $ filter (not . (`elem` cs)) $ catMaybes $ |           headMay $ filter (not . (`elem` cs)) $ catMaybes $ | ||||||
| @ -418,6 +426,7 @@ journalCheckCommoditiesDeclared j = | |||||||
|           (map (Just . acommodity) $ amounts pamount) |           (map (Just . acommodity) $ amounts pamount) | ||||||
|         cs = journalCommoditiesDeclared j |         cs = journalCommoditiesDeclared j | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| setYear :: Year -> JournalParser m () | setYear :: Year -> JournalParser m () | ||||||
| setYear y = modify' (\j -> j{jparsedefaultyear=Just y}) | setYear y = modify' (\j -> j{jparsedefaultyear=Just y}) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ module Hledger.Utils.String ( | |||||||
|  lstrip, |  lstrip, | ||||||
|  rstrip, |  rstrip, | ||||||
|  chomp, |  chomp, | ||||||
|  |  chomp1, | ||||||
|  singleline, |  singleline, | ||||||
|  elideLeft, |  elideLeft, | ||||||
|  elideRight, |  elideRight, | ||||||
| @ -37,6 +38,8 @@ module Hledger.Utils.String ( | |||||||
|  padright, |  padright, | ||||||
|  cliptopleft, |  cliptopleft, | ||||||
|  fitto, |  fitto, | ||||||
|  |  linesPrepend, | ||||||
|  |  linesPrepend2, | ||||||
|  -- * wide-character-aware layout |  -- * wide-character-aware layout | ||||||
|  charWidth, |  charWidth, | ||||||
|  strWidth, |  strWidth, | ||||||
| @ -86,10 +89,14 @@ lstrip = dropWhile isSpace | |||||||
| rstrip :: String -> String | rstrip :: String -> String | ||||||
| rstrip = reverse . lstrip . reverse | rstrip = reverse . lstrip . reverse | ||||||
| 
 | 
 | ||||||
| -- | Remove trailing newlines/carriage returns. | -- | Remove all trailing newlines/carriage returns. | ||||||
| chomp :: String -> String | chomp :: String -> String | ||||||
| chomp = reverse . dropWhile (`elem` "\r\n") . reverse | chomp = reverse . dropWhile (`elem` "\r\n") . reverse | ||||||
| 
 | 
 | ||||||
|  | -- | Remove all trailing newline/carriage returns, leaving just one trailing newline. | ||||||
|  | chomp1 :: String -> String | ||||||
|  | chomp1 = (++"\n") . chomp | ||||||
|  | 
 | ||||||
| -- | Remove consecutive line breaks, replacing them with single space | -- | Remove consecutive line breaks, replacing them with single space | ||||||
| singleline :: String -> String | singleline :: String -> String | ||||||
| singleline = unwords . filter (/="") . (map strip) . lines | singleline = unwords . filter (/="") . (map strip) . lines | ||||||
| @ -343,3 +350,14 @@ stripAnsi s = either err id $ regexReplace ansire "" s | |||||||
|  where |  where | ||||||
|    err    = error "stripAnsi: invalid replacement pattern"      -- PARTIAL, shouldn't happen |    err    = error "stripAnsi: invalid replacement pattern"      -- PARTIAL, shouldn't happen | ||||||
|    ansire = toRegex' "\ESC\\[([0-9]+;)*([0-9]+)?[ABCDHJKfmsu]"  -- PARTIAL, should succeed |    ansire = toRegex' "\ESC\\[([0-9]+;)*([0-9]+)?[ABCDHJKfmsu]"  -- PARTIAL, should succeed | ||||||
|  | 
 | ||||||
|  | -- | Add a prefix to each line of a string. | ||||||
|  | linesPrepend :: String -> String -> String | ||||||
|  | linesPrepend prefix = unlines . map (prefix++) . lines | ||||||
|  | 
 | ||||||
|  | -- | Add a prefix to the first line of a string,  | ||||||
|  | -- and a different prefix to the remaining lines. | ||||||
|  | linesPrepend2 :: String -> String -> String -> String | ||||||
|  | linesPrepend2 prefix1 prefix2 s = | ||||||
|  |   unlines $ (prefix1++l) : map (prefix2++) ls | ||||||
|  |   where l:ls = lines s | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ runCheck copts@CliOpts{rawopts_} j (check,args) = | |||||||
|     Payees          -> |     Payees          -> | ||||||
|       case journalCheckPayeesDeclared j of |       case journalCheckPayeesDeclared j of | ||||||
|         Right () -> return () |         Right () -> return () | ||||||
|         Left err -> hPutStrLn stderr err >> exitFailure |         Left err -> hPutStrLn stderr ("Error: "++err) >> exitFailure | ||||||
|   where |   where | ||||||
|     -- Hack: append the provided args to the raw opts, |     -- Hack: append the provided args to the raw opts, | ||||||
|     -- in case the check can use them (like checkdates --unique).  |     -- in case the check can use them (like checkdates --unique).  | ||||||
|  | |||||||
| @ -37,13 +37,15 @@ checkdates CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do | |||||||
|     FoldAcc{fa_previous=Nothing} -> return () |     FoldAcc{fa_previous=Nothing} -> return () | ||||||
|     FoldAcc{fa_error=Nothing}    -> return () |     FoldAcc{fa_error=Nothing}    -> return () | ||||||
|     FoldAcc{fa_error=Just error, fa_previous=Just previous} -> do |     FoldAcc{fa_error=Just error, fa_previous=Just previous} -> do | ||||||
|       putStrLn $ printf  |       let  | ||||||
|           ("Error: transaction's date is not in date order%s,\n" |         uniquestr = if unique then " and/or not unique" else "" | ||||||
|         ++ "at %s:\n\n%sPrevious transaction's date was: %s") |         positionstr = showGenericSourcePos $ tsourcepos error | ||||||
|         (if unique then " and/or not unique" else "") |         txn1str = linesPrepend  "  "      $ showTransaction previous | ||||||
|         (showGenericSourcePos $ tsourcepos error) |         txn2str = linesPrepend2 "> " "  " $ showTransaction error | ||||||
|         (showTransaction error) |       printf "Error: transaction date is out of order%s\nat %s:\n\n%s" | ||||||
|         (show $ date previous) |         uniquestr | ||||||
|  |         positionstr | ||||||
|  |         (txn1str ++ txn2str) | ||||||
|       exitFailure |       exitFailure | ||||||
| 
 | 
 | ||||||
| data FoldAcc a b = FoldAcc | data FoldAcc a b = FoldAcc | ||||||
|  | |||||||
| @ -28,6 +28,7 @@ checkdupesmode = hledgerCommandMode | |||||||
| checkdupes _opts j = do | checkdupes _opts j = do | ||||||
|   let dupes = checkdupes' $ accountsNames j |   let dupes = checkdupes' $ accountsNames j | ||||||
|   when (not $ null dupes) $ do |   when (not $ null dupes) $ do | ||||||
|  |     -- XXX make output more like Checkdates.hs, Check.hs etc. | ||||||
|     mapM_ render dupes |     mapM_ render dupes | ||||||
|     exitFailure |     exitFailure | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user