imp: errors: more error prettification

This commit is contained in:
Simon Michael 2022-07-13 02:29:36 +01:00
parent 84f951e020
commit 1c67d0860e
15 changed files with 110 additions and 49 deletions

View File

@ -115,11 +115,11 @@ transactionCheckBalanced BalancingOpts{commodity_styles_} t = errs
where
rmsg
| rsumok = ""
| not rsignsok = "The real postings all have the same sign."
| not rsignsok = "The real postings all have the same sign. Consider negating some of them."
| otherwise = "The real postings' sum should be 0 but is: " ++ showMixedAmountOneLine rsumcost
bvmsg
| bvsumok = ""
| not bvsignsok = "The balanced virtual postings all have the same sign."
| not bvsignsok = "The balanced virtual postings all have the same sign. Consider negating some of them."
| otherwise = "The balanced virtual postings' sum should be 0 but is: " ++ showMixedAmountOneLine bvsumcost
-- | Legacy form of transactionCheckBalanced.
@ -159,22 +159,34 @@ balanceTransactionHelper bopts t = do
[] -> Right (txnTieKnot t', inferredamtsandaccts)
errs -> Left $ transactionBalanceError t' errs'
where
errs' = errs ++
[ "Inference of conversion costs has been disallowed."
ismulticommodity = (length $ transactionCommodities t') > 1
errs' =
[ "Automatic commodity conversion is not enabled."
| ismulticommodity && not (infer_transaction_prices_ bopts)
] ++
errs ++
if ismulticommodity
then
[ "Consider adjusting this entry's amounts, adding missing postings,"
, "or recording conversion price(s) with @, @@ or equity postings."
]
where
ismulticommodity = (length $ mconcat $ map (maCommodities . pamount) $ tpostings t') > 1
else
[ "Consider adjusting this entry's amounts, or adding missing postings."
]
transactionCommodities :: Transaction -> S.Set CommoditySymbol
transactionCommodities t = mconcat $ map (maCommodities . pamount) $ tpostings t
-- | Generate a transaction balancing error message, given the transaction
-- and one or more suberror messages.
transactionBalanceError :: Transaction -> [String] -> String
transactionBalanceError t errs = printf "%s:\n%s\n\n%s\n%s"
transactionBalanceError t errs = printf "%s:\n%s\n\nThis %stransaction is unbalanced.\n%s"
(sourcePosPairPretty $ tsourcepos t)
(textChomp ex)
("This transaction is unbalanced."::String)
(if ismulticommodity then "multi-commodity " else "" :: String)
(chomp $ unlines errs)
where
ismulticommodity = (length $ transactionCommodities t) > 1
(_f,_l,_mcols,ex) = makeTransactionErrorExcerpt t finderrcols
where
finderrcols _ = Nothing
@ -591,12 +603,16 @@ checkBalanceAssertionOneCommodityB p@Posting{paccount=assertedacct} assertedamt
-- "display precision: %d",
"this balance was asserted: %s", -- (at display precision: %s)",
"but the actual balance is: %s", -- (at display precision: %s)",
"a difference of: %s"
"a difference of: %s",
"",
"Consider viewing this account's register to troubleshoot. Eg:",
"",
"hledger reg -I '%s'%s"
])
(sourcePosPretty pos)
(textChomp ex)
-- (showDate $ postingDate p)
(T.unpack $ paccount p) -- XXX pack
acct
(if isinclusive then " (including subaccounts)" else "" :: String)
assertedcomm
(if istotal then " (no other commodity balance allowed)" else "" :: String)
@ -606,7 +622,10 @@ checkBalanceAssertionOneCommodityB p@Posting{paccount=assertedacct} assertedamt
(show $ aquantity actualbalincomm)
-- (showAmount actualbalincommodity)
(show $ aquantity assertedamt - aquantity actualbalincomm)
(acct ++ if isinclusive then "" else "$")
(if istotal then "" else (" cur:'"++T.unpack assertedcomm++"'"))
where
acct = T.unpack $ paccount p
ass = fromJust $ pbalanceassertion p -- PARTIAL: fromJust won't fail, there is a balance assertion
pos = baposition ass
(_,_,_,ex) = makePostingErrorExcerpt p finderrcols
@ -648,7 +667,7 @@ checkBalanceAssignmentPostingDateB :: Posting -> Balancing s ()
checkBalanceAssignmentPostingDateB p =
when (hasBalanceAssignment p && isJust (pdate p)) $
throwError $ chomp $ unlines [
"can't use balance assignment with custom posting date"
"Balance assignments and custom posting dates may not be combined."
,""
,chomp1 $ T.unpack $ maybe (T.unlines $ showPostingLines p) showTransaction $ ptransaction p
,"Balance assignments may not be used on postings with a custom posting date"
@ -664,7 +683,7 @@ checkBalanceAssignmentUnassignableAccountB p = do
unassignable <- R.asks bsUnassignable
when (hasBalanceAssignment p && paccount p `S.member` unassignable) $
throwError $ chomp $ unlines [
"can't use balance assignment with auto postings"
"Balance assignments and auto postings may not be combined."
,""
,chomp1 $ T.unpack $ maybe (T.unlines $ showPostingLines p) (showTransaction) $ ptransaction p
,"Balance assignments may not be used on accounts affected by auto posting rules"

View File

@ -40,8 +40,16 @@ journalCheckAccounts j = mapM_ checkacct (journalPostings j)
where
checkacct p@Posting{paccount=a}
| a `elem` journalAccountNamesDeclared j = Right ()
| otherwise = Left $
printf "%s:%d:\n%sundeclared account \"%s\"\n" f l ex a
| otherwise = Left $ printf (unlines [
"%s:%d:"
,"%s"
,"Strict account checking is enabled, and"
,"account %s has not been declared."
,"Consider adding an account directive. Examples:"
,""
,"account %s"
,"account %s ; type:A ; (L,E,R,X,C,V)"
]) f l ex (show a) a a
where
(f,l,_mcols,ex) = makePostingErrorExcerpt p finderrcols
-- Calculate columns suitable for highlighting the excerpt.
@ -61,7 +69,16 @@ journalCheckCommodities j = mapM_ checkcommodities (journalPostings j)
case findundeclaredcomm p of
Nothing -> Right ()
Just (comm, _) ->
Left $ printf "%s:%d:\n%sundeclared commodity \"%s\"\n" f l ex comm
Left $ printf (unlines [
"%s:%d:"
,"%s"
,"Strict commodity checking is enabled, and"
,"commodity %s has not been declared."
,"Consider adding a commodity directive. Examples:"
,""
,"commodity %s1000.00"
,"commodity 1.000,00 %s"
]) f l ex (show comm) comm comm
where
(f,l,_mcols,ex) = makePostingErrorExcerpt p finderrcols
where
@ -122,7 +139,15 @@ journalCheckPayees j = mapM_ checkpayee (jtxns j)
checkpayee t
| payee `elem` journalPayeesDeclared j = Right ()
| otherwise = Left $
printf "%s:%d:\n%sundeclared payee \"%s\"\n" f l ex payee
printf (unlines [
"%s:%d:"
,"%s"
,"Strict payee checking is enabled, and"
,"payee %s has not been declared."
,"Consider adding a payee directive. Examples:"
,""
,"payee %s"
]) f l ex (show payee) payee
where
payee = transactionPayee t
(f,l,_mcols,ex) = makeTransactionErrorExcerpt t finderrcols

View File

@ -6,10 +6,12 @@ where
import Control.Monad (forM)
import Data.List (groupBy)
import Text.Printf (printf)
import qualified Data.Text as T (pack, unlines)
import Hledger.Data.Errors (makeTransactionErrorExcerpt)
import Hledger.Data.Transaction (transactionFile, transactionDateOrDate2)
import Hledger.Data.Types
import Hledger.Utils (textChomp)
journalCheckOrdereddates :: WhichDate -> Journal -> Either String ()
journalCheckOrdereddates whichdate j = do
@ -25,13 +27,17 @@ journalCheckOrdereddates whichdate j = do
FoldAcc{fa_previous=Nothing} -> Right ()
FoldAcc{fa_error=Nothing} -> Right ()
FoldAcc{fa_error=Just t, fa_previous=Just tprev} -> Left $ printf
"%s:%d:\n%stransaction date%s is out of order with previous transaction date %s"
f l ex datenum tprevdate
("%s:%d:\n%s\nOrdered dates checking is enabled, and this transaction's\n"
++ "date%s (%s) is out of order with the previous transaction.\n"
++ "Consider moving this entry into date order, or adjusting its date.")
f l ex datenum (show $ getdate t)
where
(f,l,_mcols,ex) = makeTransactionErrorExcerpt t finderrcols
(_,_,_,ex1) = makeTransactionErrorExcerpt tprev (const Nothing)
(f,l,_,ex2) = makeTransactionErrorExcerpt t finderrcols
-- separate the two excerpts by a space-beginning line to help flycheck-hledger parse them
ex = T.unlines [textChomp ex1, T.pack " ", textChomp ex2]
finderrcols _t = Just (1, Just 10)
datenum = if whichdate==SecondaryDate then "2" else ""
tprevdate = show $ getdate tprev
data FoldAcc a b = FoldAcc
{ fa_error :: Maybe a

View File

@ -17,6 +17,7 @@ import Hledger.Data.Errors (makePostingErrorExcerpt)
import Hledger.Data.Journal (journalPostings, journalAccountNamesUsed)
import Hledger.Data.Posting (isVirtual)
import Hledger.Data.Types
import Hledger.Utils (chomp)
-- | Check that all the journal's postings are to accounts with a unique leaf name.
-- Otherwise, return an error message for the first offending posting.
@ -46,9 +47,13 @@ checkposting :: [(Text,[AccountName])] -> Posting -> Either String ()
checkposting leafandfullnames p@Posting{paccount=a} =
case [lf | lf@(_,fs) <- leafandfullnames, a `elem` fs] of
[] -> Right ()
(leaf,fulls):_ -> Left $ printf
"%s:%d:\n%saccount leaf name \"%s\" is not unique\nit is used in account names: %s"
f l ex leaf accts
(leaf,fulls):_ -> Left $ chomp $ printf
("%s:%d:\n%s\nChecking for unique account leaf names is enabled, and\n"
++"account leaf name %s is not unique.\n"
++"It appears in these account names:\n%s"
++"\nConsider changing these account names so their last parts are different."
)
f l ex (show leaf) accts
where
-- t = fromMaybe nulltransaction ptransaction -- XXX sloppy
(f,l,_mcols,ex) = makePostingErrorExcerpt p finderrcols
@ -59,4 +64,4 @@ checkposting leafandfullnames p@Posting{paccount=a} =
llen = T.length $ accountLeafName a
col = 5 + (if isVirtual p then 1 else 0) + alen - llen
col2 = col + llen - 1
accts = T.intercalate ", " $ map (("\""<>).(<>"\"")) fulls
accts = T.unlines fulls -- $ map (("\""<>).(<>"\"")) fulls

View File

@ -498,11 +498,12 @@ datep' mYear = do
let dateStr = show year ++ [sep1] ++ show month ++ [sep2] ++ show day
when (sep1 /= sep2) $ customFailure $ parseErrorAtRegion startOffset endOffset $
"invalid date: separators are different, should be the same"
"This date is malformed because the separators are different.\n"
++"Please use consistent separators."
case fromGregorianValid year month day of
Nothing -> customFailure $ parseErrorAtRegion startOffset endOffset $
"well-formed but invalid date: " ++ dateStr
"This date is invalid, please correct it: " ++ dateStr
Just date -> pure $! date
partialDate :: Int -> Maybe Year -> Month -> Char -> MonthDay -> TextParser m Day
@ -512,12 +513,13 @@ datep' mYear = do
Just year ->
case fromGregorianValid year month day of
Nothing -> customFailure $ parseErrorAtRegion startOffset endOffset $
"well-formed but invalid date: " ++ dateStr
"This date is invalid, please correct it: " ++ dateStr
Just date -> pure $! date
where dateStr = show year ++ [sep] ++ show month ++ [sep] ++ show day
Nothing -> customFailure $ parseErrorAtRegion startOffset endOffset $
"partial date "++dateStr++" found, but the current year is unknown"
"The partial date "++dateStr++" can not be parsed because the current year is unknown.\n"
++"Consider making it a full date, or add a default year directive.\n"
where dateStr = show month ++ [sep] ++ show day
{-# INLINABLE datep' #-}

View File

@ -134,7 +134,7 @@ toRegexCI = memo $ \s -> mkRegexErr s (RegexpCI s <$> makeRegexOptsM defaultComp
-- | Make a nice error message for a regexp error.
mkRegexErr :: Text -> Maybe a -> Either RegexError a
mkRegexErr s = maybe (Left errmsg) Right
where errmsg = T.unpack $ "this regular expression could not be compiled: " <> s
where errmsg = T.unpack $ "This regular expression is malformed, please correct it:\n" <> s
-- Convert a Regexp string to a compiled Regex, throw an error
toRegex' :: Text -> Regexp

View File

@ -120,8 +120,10 @@ parseErrorAtRegion
-> HledgerParseErrorData
parseErrorAtRegion startOffset endOffset msg =
if startOffset < endOffset
then ErrorFailAt startOffset endOffset msg
else ErrorFailAt startOffset (startOffset+1) msg
then ErrorFailAt startOffset endOffset msg'
else ErrorFailAt startOffset (startOffset+1) msg'
where
msg' = "\n" ++ msg
--- * Re-parsing

View File

@ -10,7 +10,7 @@ $ hledger -f- check accounts
2020-01-01
(a) 1
$ hledger -f- check accounts
>2 /undeclared account "a"/
>2 /account "a" has not been declared/
>=1
# 3. also fails for forecast accounts
@ -20,12 +20,12 @@ account a
a $1
b
$ hledger -f- --today 2022-01-01 --forecast check accounts
>2 /undeclared account "b"/
>2 /account "b" has not been declared/
>=1
# 4. also fails in --strict mode
$ hledger -f- --today 2022-01-01 --forecast --strict bal
>2 /undeclared account "b"/
>2 /account "b" has not been declared/
>=1
# 5. also fails for auto accounts
@ -40,10 +40,10 @@ account a
2022-02-01
$ hledger -f- --auto check accounts
>2 /undeclared account "b"/
>2 /account "b" has not been declared/
>=1
# 6. also fails in --strict mode
$ hledger -f- --auto --strict bal
>2 /undeclared account "b"/
>2 /account "b" has not been declared/
>=1

View File

@ -10,7 +10,7 @@ $ hledger -f- check commodities
2020-01-01
(a) $1
$ hledger -f- check commodities
>2 /undeclared commodity "\$"/
>2 /commodity "\$" has not been declared/
>=1
# 3. But commodityless zero amounts will not fail
@ -27,5 +27,5 @@ $ hledger -f- check commodities
(a) $0
$ hledger -f- check commodities
>2 /undeclared commodity "\$"/
>2 /commodity "\$" has not been declared/
>=1

View File

@ -12,7 +12,7 @@ $ hledger -f- check ordereddates
2020-01-01
(a) 1
$ hledger -f- check ordereddates
>2 /transaction date is out of order/
>2 /date .*is out of order/
>=1
# With --date2, it checks secondary dates instead
@ -26,7 +26,7 @@ $ hledger -f- check ordereddates --date2
2020-01-01=2020-01-03
2020-01-02
$ hledger -f- check ordereddates --date2
>2 /transaction date2 is out of order/
>2 /date2 .*is out of order/
>=1
# XXX not supported: With a query, only matched transactions' dates are checked.

View File

@ -9,7 +9,7 @@ $ hledger -f - check payees
<
2020-01-01 foo
$ hledger -f - check payees
>2 /undeclared payee "foo"/
>2 /payee "foo" has not been declared/
>=1
# or:
@ -17,5 +17,5 @@ $ hledger -f - check payees
payee foo
2020-01-01 the payee | foo
$ hledger -f - check payees
>2 /undeclared payee "the payee"/
>2 /payee "the payee" has not been declared/
>=1

View File

@ -160,7 +160,7 @@ $ hledger -f- print --auto -x
# 9.
$ hledger print -f- --auto
>2 /can't use balance assignment with auto postings/
>2 /Balance assignments and auto postings may not be combined/
>=1

View File

@ -225,7 +225,7 @@ $ hledger -f - stats
b =$-1 ; date:2012/1/1
$ hledger -f - stats
>2 /can't use balance assignment with custom posting date/
>2 /Balance assignments and custom posting dates may not be combined/
>=1
# 13. Posting Date

View File

@ -5,7 +5,7 @@ hledger -f- print
2010/31/12 x
a 1
b
>>>2 /invalid date/
>>>2 /date is invalid/
>>>= 1
# 2. too-large day
hledger -f- print
@ -13,7 +13,7 @@ hledger -f- print
2010/12/32 x
a 1
b
>>>2 /invalid date/
>>>2 /date is invalid/
>>>= 1
# 3. 29th feb on leap year should be ok
hledger -f- print
@ -33,7 +33,7 @@ hledger -f- print
2001/2/29 x
a 1
b
>>>2 /invalid date/
>>>2 /date is invalid/
>>>= 1
# 5. dates must be followed by whitespace or newline
hledger -f- print

View File

@ -128,8 +128,10 @@ hledger: Error: -:1-3:
| a 1A
| b 1B
This transaction is unbalanced.
The real postings all have the same sign.
This multi-commodity transaction is unbalanced.
The real postings all have the same sign. Consider negating some of them.
Consider adjusting this entry's amounts, adding missing postings,
or recording conversion price(s) with @, @@ or equity postings.
>=1
# 12. Typical "hledger equity --close" transaction does not trigger sign error.