crystal has the ability to generate very descriptive backtraces at compile time:
$ cat go2.cr
$ crystal build --error-trace go2.cr
5 | go1
Error: instantiating ‘go1()’
2 | go3
Error: undefined local variable or method ‘go3’ for top-level
Did you mean ‘go1’?
I had a thought that maybe runtime exception traces, like this one:
$ cat go.cr
$ crystal go.cr
Unhandled exception: BOOM (Exception)
from go.cr:1:1 in ‘__crystal_main’
from /usr/share/crystal/src/crystal/main.cr:97:5 in ‘main_user_code’
from /usr/share/crystal/src/crystal/main.cr:86:7 in ‘main’
from /usr/share/crystal/src/crystal/main.cr:106:3 in ‘main’
could possibly be aumented so that they show more information, like looking up the source code on the lines of the backtrace, at runtime. Thoughts?
This might help debugging during development, but it wouldn’t be useful in production. The additional verbosity would fill up logs and provide no benefit. Often source code wouldn’t be available anyway in the runtime environment. And these enhancements for runtime errors would add a bunch of additional code to every Crystal program, again with often no real gain.
It would be possible though to have enhanced backtraces for development. This should be pretty easy to implement, and could even go entirely into user code. Essentially, you just need to override
Callstack.print_frame and enhance the frame output.
An alternative solution would be to pipe stderr through a program that enhances the backtraces. That might actually be easier to implement and it’s more flexible because it doesn’t need to be activated at compile time and you can even enhance backtraces from logs.
Raven.cr’s crash handler would be an example for parsing the error output from a Crystal program and enhancing it: https://github.com/Sija/raven.cr/blob/master/src/crash_handler.cr
Thanks. I’ll try making one a shard and if I really like it propose it for the stdlib (in non release compiles only perhaps? :)