How to Force Ruby to Show a Full Stack Trace

How can I force Ruby to show a full stack trace?

begin
# Code that raises exception
rescue StandardError => e
puts e.backtrace
end

How do I get ruby to print a full backtrace instead of a truncated one?

Exception#backtrace has the entire stack in it:

def do_division_by_zero; 5 / 0; end
begin
do_division_by_zero
rescue => exception
puts exception.backtrace
raise # always reraise
end

(Inspired by Peter Cooper's Ruby Inside blog)

How to get stack trace from a Test::Unit::TestCase

Looking through the code of Test::Unit in Ruby 1.8, it seems all the errors go through the Test::Unit::Error object which filters the backtrace in its #long_display method. There is no configuration and all runners will use the same filtered trace.

Brute force monkey patch to get the whole trace: (I put this in my single test case file; perhaps you could put it in a test helper)

require 'test/unit/util/backtracefilter'

module Test::Unit::Util::BacktraceFilter
def filter_backtrace(backtrace, prefix=nil)
backtrace
end
end

And monkey patch for Ruby 1.9 (which uses minitest)

def MiniTest.filter_backtrace(bt)
bt
end

Log full stacktrace in rails including all gems

Depending on what version of rails you are using this may help:

http://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html#method-i-remove_silencers-21

Force ruby to hide backtrace on exception

It seems that you are using the "sh" command in the rake task to start the compiler. In that case you should catch a RuntimeError, in order to get this error. Something like this:

task "foo" do
begin
sh "bar"
rescue RuntimeError => e
puts e.message
exit(1)
end
end

Configure Rails Logger to store full stack trace by default

When you put your app on the highest log level (which is ":debug"), you'd get what want:

Rails guides on log level

Jruby Stack Traces

I've never worked with Java exceptions in Ruby, but AFAIK, Java exceptions get presented to you as Ruby exceptions, which means you can get the exception message by sending the :message message to the exception object:

begin
# stuff
rescue JavaSql::SQLException => e
puts "#{e.class}: #{e.message}"
end

Is that what you mean? I'm not quite sure what you would need the stacktrace for in this particular situation, so I probably misunderstood.

Thread.dumpStack equivalent in Ruby

Kernel#caller will give you the current call stack in array form. You can also set a starting and ending frame if you'd like only a portion of the stack.

def a(skip)
caller(skip)
end
def b(skip)
a(skip)
end
def c(skip)
b(skip)
end
c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"]
c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"]
c(2) #=> ["prog:8:in `c'", "prog:12:in `<main>'"]
c(3) #=> ["prog:13:in `<main>'"]
c(4) #=> []
c(5) #=> nil

How to suppress backtrace in Rails?

You have total control over the backtrace returned with an exception instance by using its set_backtrace method. For example:

def strip_backtrace
yield
rescue => err
err.set_backtrace([])
raise err
end

begin
strip_backtrace do
puts 'hello'
raise 'ERROR!'
end
rescue => err
puts "Error message: #{err.message}"
puts "Error backtrace: #{err.backtrace}"
end

Output:

hello
Error message: ERROR!
Error backtrace: []

The strip_backtrace method here catches all errors, sets the backtrace to an empty array, and re-raises the modified exception.

Is there any way to get reasonable stack traces in jruby?

I will often force compilation of the code with jruby.compile.mode=FORCE, as the compiled code will have the Ruby names and line numbers in the stack traces. This makes things generally slower, so I don't leave it on all the time.

As of JRuby 1.7.10, try setting jruby.rewrite.java.trace to true.

EDIT

From that same Twitter discussion, another idea is to use

rescue NativeException
raise
end

Which might also help. Of course, you have to know about where the exception occurs, but it should help in a pinch.



Related Topics



Leave a reply



Submit