Compressing or modifying exception backtraces

In PageTemplate, a project of mine with Brian Wisti, we provide a framework of sorts that has a large number of layers between the call to PageTemplate.output, and a point where the user's own code is later called.

If an error exists in the user's code, it looks somewhat like this:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in `fullname': undefined local variable or method `last_nam' for #<User:0xb7b92e38> (NameError)
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:86:in `send'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:86:in `get'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:78:in `each'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:78:in `get'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:248:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `map'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
     ... 13 levels...
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

About 23 levels of output of PageTemplate alone.

What I'd like is to shorten that to one:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in `fullname': undefined local variable or method `last_nam' for #<User:0xb7b92e38> (NameError)
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

Is there any safe way to do this?

Alternately, I'd also like to potentially generate output like this:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in `fullname': undefined local variable or method `last_nam' for #<User:0xb7b92e38> (NameError)
   from Template:user_profile.html in "Value: user.fullname"
   from Template:user_profile.html in "If: user"
   from Template:main_page.html in "Include user_profile.html"
   from Template:main_page.html in "Loop users: user"
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

Considerably more useful for the developer using PT.

Is it possible to modify the backtrace like this?

Thanks,

- Greg

You could expand on this theme:

#!/usr/bin/ruby

def recurse(i)
  raise "No more recursion please" if i == 0
  recurse_a(i-1)
end

def recurse_a(i)
  recurse(i)
end

begin
  recurse(1000)
rescue => e
  puts e.inspect
  puts e.backtrace[0], '...', e.backtrace[-2..-1]
end

regards,

Brian

···

On 29/04/05, Greg Millam <ruby-talk@lethalcode.net> wrote:

In PageTemplate, a project of mine with Brian Wisti, we provide a
framework of sorts that has a large number of layers between the call to
PageTemplate.output, and a point where the user's own code is later called.

If an error exists in the user's code, it looks somewhat like this:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in
`fullname': undefined local variable or method `last_nam' for
#<User:0xb7b92e38> (NameError)
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:86:in `send'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:86:in `get'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:78:in `each'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/parser.rb:78:in `get'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:248:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `map'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
     ... 13 levels...
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:145:in `output'
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

About 23 levels of output of PageTemplate alone.

What I'd like is to shorten that to one:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in
`fullname': undefined local variable or method `last_nam' for
#<User:0xb7b92e38> (NameError)
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

Is there any safe way to do this?

Alternately, I'd also like to potentially generate output like this:

/home/walker/public_html/deafcode/rbsource/user_instance.rb:3:in
`fullname': undefined local variable or method `last_nam' for
#<User:0xb7b92e38> (NameError)
   from Template:user_profile.html in "Value: user.fullname"
   from Template:user_profile.html in "If: user"
   from Template:main_page.html in "Include user_profile.html"
   from Template:main_page.html in "Loop users: user"
   from /usr/lib/ruby/site_ruby/1.8/PageTemplate/commands.rb:187:in `output'
   from /home/walker/public_html/deafcode/rbsource/site.rb:90:in `output'
from index.cgi:23

Considerably more useful for the developer using PT.

Is it possible to modify the backtrace like this?

Thanks,

- Greg

--
http://ruby.brian-schroeder.de/

multilingual _non rails_ ruby based vocabulary trainer:
http://www.vocabulaire.org/ | http://www.gloser.org/ | http://www.vokabeln.net/