
Hello, I'm getting really frustrated by error handling in haskell. By this I mean "assert"-like errors. Which means, something that should never happen, happens. This will happen in the development and deployment of software of any size. When coding the feature you'll say, I don't need to handle the "Nothing" case, because it will never happen, or almost never, and this is not critical production software. But if one day it happens you find yourself with a several thousand lines program and all you have to debug is the input data (most of the time anyway, sometimes not even that) and this error message (for instance): *** Exception: Prelude.head: empty list And you don't know even, did you call "head" or maybe a library you are using called it. This is really poor compared to what Java, python and others offers. I can understand that it's difficult to provide a stack trace, especially with lazy evaluation, but at least the function name and maybe a line number... Actually I don't know why it would be so difficult to also give me the values of the parameters of the function... using print and if it's a pure function it intuitively doesn't seem difficult. I've tried ghci with :trace and ":set -fbreak-on-exception" and I got nowhere. It breaks in things which are not important (I have no idea where it breaks, it claims an exception was thrown, maybe but not in my code and it never reaches my code for sure). After hitting ":continue" many times, I get to my exception and there I didn't manage to get useful information (:hist never printed me anything). But I would like not to have to use ghci at all. And to avoid having to write all over the place in my code these "else" and case situations for things I assume are impossible (these are cases I would not write in other modern languages). This is a feature for which I would be ready to pay a 50% speed penalty and 50% memory use penalty. I understand if it's the haskell way of writing all those else clauses... But I think in that case it really makes it compare negatively to other languages. It would be a real minus in my opinion (including to code readability). I have read (quickly) those but didn't find the solution there: http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/ghci-debugger.html http://book.realworldhaskell.org/read/error-handling.html Any advice will be welcome! I really hope I missed something. Emmanuel

Hi Emmanuel, It is indeed good practice to write total programs in general. However, I understand the need for stack traces in practice. There are some slides by Simon Marlow on the issue, ironically using your example in the title. In short: check the -xc flag in http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/runtime-control.html Hope this helps, Ozgur

On 6 November 2012 12:02, Ozgur Akgun
There are some slides by Simon Marlow on the issue, ironically using your example in the title.
Sorry, forgot to add the link to slides: http://community.haskell.org/~simonmar/slides/HIW11.pdf

well it certainly requires will to build with profiling.
i had to reinstall all my cabal packages with profiling enabled, which i
finally managed to do now..
and now it tells me:
ghc -prof -auto-all Prog.hs
Dynamic linking required, but this is a non-standard build (eg. prof).
You need to build the program twice: once the normal way, and then
in the desired way using -osuf to set the object file suffix.
Ah well.. I'll fight some more with this later. Not exactly "out of the
box"...
Emmanuel
On Tue, Nov 6, 2012 at 1:02 PM, Ozgur Akgun
Hi Emmanuel,
It is indeed good practice to write total programs in general. However, I understand the need for stack traces in practice.
There are some slides by Simon Marlow on the issue, ironically using your example in the title.
In short: check the -xc flag in http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/runtime-control.html
Hope this helps, Ozgur

OK apparently i just needed to build normally then again with:
ghc -prof -auto-all -osuf prof *.hs
Well the instructions were clear but it was after the big fight with cabal.
Well now the executable is 47Mb compared to 23Mb before, but if I'll get
the stack it's worth it. It's running now, it takes a while before it hits
the crash.
Emmanuel
On Tue, Nov 6, 2012 at 8:34 PM, Emmanuel Touzery
well it certainly requires will to build with profiling. i had to reinstall all my cabal packages with profiling enabled, which i finally managed to do now..
and now it tells me: ghc -prof -auto-all Prog.hs
Dynamic linking required, but this is a non-standard build (eg. prof). You need to build the program twice: once the normal way, and then in the desired way using -osuf to set the object file suffix.
Ah well.. I'll fight some more with this later. Not exactly "out of the box"...
Emmanuel
On Tue, Nov 6, 2012 at 1:02 PM, Ozgur Akgun
wrote: Hi Emmanuel,
It is indeed good practice to write total programs in general. However, I understand the need for stack traces in practice.
There are some slides by Simon Marlow on the issue, ironically using your example in the title.
In short: check the -xc flag in http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/runtime-control.html
Hope this helps, Ozgur

so in the end I had to build the program with:
ghc -prof -auto-all -rtsopts -osuf prof *.hs
so also -rtsopts. After the simple ghc *.hs build.
then I run it with:
+RTS -xc -RTS
in the command-line.
but it doesn't appear to work properly, I guess I didn't quite compile or
run it correctly. It constantly displays me some stack position during the
whole runtime even when there is no problem.
When the real problem comes, it still displays the same stack it did for
the whole runtime, but there is no "head" in that function.
I'll probably end up debugging this one "by hand", but I would really would
like to have a general solution for the problem for the future, where
tooling would help me...
annotating/modifying my code... it really seems wrong in this case :-/
On Tue, Nov 6, 2012 at 8:34 PM, Emmanuel Touzery
well it certainly requires will to build with profiling. i had to reinstall all my cabal packages with profiling enabled, which i finally managed to do now..
and now it tells me: ghc -prof -auto-all Prog.hs
Dynamic linking required, but this is a non-standard build (eg. prof). You need to build the program twice: once the normal way, and then in the desired way using -osuf to set the object file suffix.
Ah well.. I'll fight some more with this later. Not exactly "out of the box"...
Emmanuel
On Tue, Nov 6, 2012 at 1:02 PM, Ozgur Akgun
wrote: Hi Emmanuel,
It is indeed good practice to write total programs in general. However, I understand the need for stack traces in practice.
There are some slides by Simon Marlow on the issue, ironically using your example in the title.
In short: check the -xc flag in http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/runtime-control.html
Hope this helps, Ozgur

From what I can tell on the link that I found, the person ended up using a
well studying it further it seems the output I got was:
so in the end I had to build the program with:
ghc -prof -auto-all -rtsopts -osuf prof *.hs
so also -rtsopts. After the simple ghc *.hs build.
then I run it with:
+RTS -xc -RTS
in the command-line.
but it doesn't appear to work properly, I guess I didn't quite compile or run it correctly. It constantly displays me some stack position during the whole runtime even when there is no problem. When the real problem comes, it still displays the same stack it did for the whole runtime, but there is no "head" in that function.
I'll probably end up debugging this one "by hand", but I would really would like to have a general solution for the problem for the future, where tooling would help me...
annotating/modifying my code... it really seems wrong in this case :-/
On Tue, Nov 6, 2012 at 8:34 PM, Emmanuel Touzery
wrote: well it certainly requires will to build with profiling. i had to reinstall all my cabal packages with profiling enabled, which i finally managed to do now..
and now it tells me: ghc -prof -auto-all Prog.hs
Dynamic linking required, but this is a non-standard build (eg. prof). You need to build the program twice: once the normal way, and then in the desired way using -osuf to set the object file suffix.
Ah well.. I'll fight some more with this later. Not exactly "out of the box"...
Emmanuel
On Tue, Nov 6, 2012 at 1:02 PM, Ozgur Akgun
wrote: Hi Emmanuel,
It is indeed good practice to write total programs in general. However, I understand the need for stack traces in practice.
There are some slides by Simon Marlow on the issue, ironically using your example in the title.
In short: check the -xc flag in http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/runtime-control.html
Hope this helps, Ozgur

Yes, I've had similar problems with that %$#*! "*** Exception: Prelude.head: empty list" exception. When I was newer to Haskell, I was very worried about how often I might encounter that sort of problem. If it gives you any hope or comfort, over time I haven't found this to be much too of a problem in practice. In addition to the debugger, another valuable tool is Debug.Trace (see http://hackage.haskell.org/packages/archive/base/latest/doc/html/Debug-Trace...). It basically allows you to add some temporary debug print to your code. I find it particularly useful that "empty list" exception.
participants (3)
-
Amy de Buitléir
-
Emmanuel Touzery
-
Ozgur Akgun