I'm uncertain about the correct way to report errors from read
creating an instance in response to user input at the command line within a main = do ...
.
Specifically, I have a constructor that validates its arguments and reports an error in the usual way
-- ...
Right cfg -> cfg
Left err -> error (show err)
and an implementation of read
that uses this constructor. However inside my implementation I have a cryptic note (inherited from some long-ago research that I've since lost track of) that removes error information
instance Read ... where
readsPrec _ i = case ...
Right cfg -> [(cfg, "")]
Left _ -> [] -- Loses error information, but conforms to specification of 'readsPrec' in 'Read'
so that my command line parser
main :: IO ()
main = do
... read
reports all errors generated by the constructor as merely
Prelude.read: no parse
If I ignore my cryptic comment and instead have
Left err -> error (show err)
in the constructor, then I get complete error information reported to the user:
script: Detailed error information here
CallStack (from HasCallStack):
error, called at ./Pkg/Module.hs:371:57 in main:Pkg.Module
(though with stack and line information I'd rather not report in this context).
So I have three related questions about this:
read
using Left err -> error (show err)
?Left err -> []
is required there, how do I report read
or constructor errors at the command line?and (not as important)
read
in my main = do ...
?error
calls. It is frequently useful to know from pure code that read
(well, reads
) has failed.Read
for parsing that lets you report errors more clearly. Each of the popular parser-combinator libraries have facilities for good error reporting.errorWithoutStackTrace
.