Permalink
Browse files

lib: include source info in txn balance errors

Partially address #904
  • Loading branch information...
ony authored and simonmichael committed Oct 23, 2018
1 parent 119e1e3 commit 1aac38d3d37fd58f60a900d60ea6de1613d10773
Showing with 35 additions and 8 deletions.
  1. +7 −6 hledger-lib/Hledger/Data/Transaction.hs
  2. +28 −2 tests/journal/parse-errors.test
@@ -335,13 +335,13 @@ balanceTransactionUpdate :: MonadError String m
-> Maybe (Map.Map CommoditySymbol AmountStyle)
-> Transaction -> m Transaction
balanceTransactionUpdate update mstyles t =
finalize =<< inferBalancingAmount update (fromMaybe Map.empty mstyles) t
(finalize =<< inferBalancingAmount update (fromMaybe Map.empty mstyles) t)
`catchError` (throwError . annotateErrorWithTxn t)
where
finalize t' = let t'' = inferBalancingPrices t'
in if isTransactionBalanced mstyles t''
then return $ txnTieKnot t''
else throwError $ printerr $ nonzerobalanceerror t''
printerr s = intercalate "\n" [s, showTransactionUnelided t]
else throwError $ nonzerobalanceerror t''
nonzerobalanceerror :: Transaction -> String
nonzerobalanceerror t = printf "could not balance this transaction (%s%s%s)" rmsg sep bvmsg
where
@@ -354,6 +354,8 @@ balanceTransactionUpdate update mstyles t =
++ showMixedAmount (costOfMixedAmount bvsum)
sep = if not (null rmsg) && not (null bvmsg) then "; " else "" :: String
annotateErrorWithTxn t e = intercalate "\n" [showGenericSourcePos $ tsourcepos t, e, showTransactionUnelided t]
-- | Infer up to one missing amount for this transactions's real postings, and
-- likewise for its balanced virtual postings, if needed; or return an error
-- message if we can't.
@@ -368,14 +370,13 @@ inferBalancingAmount :: MonadError String m =>
-> m Transaction
inferBalancingAmount update styles t@Transaction{tpostings=ps}
| length amountlessrealps > 1
= throwError $ printerr "could not balance this transaction - can't have more than one real posting with no amount (remember to put 2 or more spaces before amounts)"
= throwError "could not balance this transaction - can't have more than one real posting with no amount (remember to put 2 or more spaces before amounts)"
| length amountlessbvps > 1
= throwError $ printerr "could not balance this transaction - can't have more than one balanced virtual posting with no amount (remember to put 2 or more spaces before amounts)"
= throwError "could not balance this transaction - can't have more than one balanced virtual posting with no amount (remember to put 2 or more spaces before amounts)"
| otherwise
= do postings <- mapM inferamount ps
return t{tpostings=postings}
where
printerr s = intercalate "\n" [s, showTransactionUnelided t]
(amountfulrealps, amountlessrealps) = partition hasAmount (realPostings t)
realsum = sumStrict $ map pamount amountfulrealps
(amountfulbvps, amountlessbvps) = partition hasAmount (balancedVirtualPostings t)
@@ -34,19 +34,45 @@ $ hledger -f - print
# 3. So in these tests we must sometimes force the desired format, like so.
# Now we see the error from the journal reader.
$ hledger -f journal:- print
>2 /hledger: could not balance this transaction \(real postings are off by 1\)/
>2 /could not balance this transaction \(real postings are off by 1\)/
>=1
# 4. We expect to have reference to line number with last posting
$ hledger -f journal:- print
>2 /\<2\>/
>=1
# A posting without two spaces between account and amount.
<
2018/1/1
(a) 1
# 4. hledger doesn't detect this as an error directly, it parses account name "(a) 1" and
# 5. hledger doesn't detect this as an error directly, it parses account name "(a) 1" and
# amount 0 here.
$ hledger -f - print -x
2018/01/01
(a) 1 0
>=
# 6. Two (or more) postings with implicit amount cannot be balanced.
<
2018/1/1
a 1
b
c
$ hledger -f journal:- print
>2 /\<4\>/
>=1
# 7. Two (or more) virtual postings with implicit amount cannot be balanced.
<
2018/1/1
[a] 1
[b]
[c]
$ hledger -f journal:- print
>2 /\<4\>/
>=1

0 comments on commit 1aac38d

Please sign in to comment.