How can I get more information about where a Haskell error has occurred? For example, yesterday I was working on a Haskell program that parses an input file, transforms the data and then prints out reporting information.
At one point, I ran "main" and got back
*** Prelude.read: parse error
with no other information. Fortunately, I knew I was calling read in only one place and was able to fix it, but for the future:
- Is it possible to get a backtrace or a line number for errors like these?
- Is it possible to get the actual data that triggered the error, i.e. the string that caused the parse error?
Thanks!
Edit Using GHC.
You might consider using a monadic
read
as in "Practical Haskell: shell scripting with error handling and privilege separation" by fellow StackOverflow user dons:If you can run the code in ghci, then the debugger can do everything you want. Here's a program that raises an exception
Now load it into ghci and use the debugger, as documented here: http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#ghci-debugger-exceptions
It lets you step around in the evaluation history, highlights the actual expression that raised the exception (bold rather than starred on a terminal), and lets you inspect the local variables.
Another option is to recompile with profiling and some flags to tag appropriate cost centers, and run with the -xc profiling option which prints the cost center stack on uncaught exceptions http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-time-options.html
The reason this is a bit difficult is described a bit earlier on the debugger page http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#tracing Basically, efficient Haskell execution doesn't use anything resembling a normal call stack, so to get that kind of information on an exception you have to be running in some special mode (debugging or profiling) which does keep that sort of information.
You didn't tell us which compiler you are using. If you use GHC, then you should take a look at the GHCi Debugger.
Stack tracing in Haskell is not trivial, because of its laziness. Nevertheless, the aforementioned debugger provides some tools (see section 2.5.5. Tracing and history in the above URL).
In general it is up to you to handle error in such a fashion that there is enough context for you to debug the cause.
The lazyness of Haskell makes stack traces difficult to implement, because the call stack might not exist any longer by the time the error happens.
A simple way of error handling is to use the Either type which allows your to return a value when things went right, or some context (error message, the input string, ...) in case of an error.
Finally, in you specific case
read
is throwing an exception so you would have to catch that and then handle the error in the calling code (have a look in theControl.Exception
package).you can get the string that caused the parse error by importing
Debug.Trace
and changing your call