Make backtrace_cleaner work as expected. Prior to this patch, the Full Trace rarely showed the full trace. Also, increase performance considerably.

This commit is contained in:
José Valim 2010-05-03 12:54:52 +02:00
parent 0e00f428a8
commit 8ae9b05fa0
2 changed files with 17 additions and 38 deletions

@ -21,17 +21,18 @@ def initialize(paths, path, details, partial)
super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}")
end
end
class Template
# The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a
# bunch of intimate details and uses it to report a very precise exception message.
class Error < ActionViewError #:nodoc:
SOURCE_CODE_RADIUS = 3
attr_reader :original_exception
attr_reader :original_exception, :backtrace
def initialize(template, assigns, original_exception)
@template, @assigns, @original_exception = template, assigns.dup, original_exception
@backtrace = compute_backtrace
@backtrace = original_exception.backtrace
end
def file_name
@ -42,14 +43,6 @@ def message
ActiveSupport::Deprecation.silence { original_exception.message }
end
def clean_backtrace
if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
Rails.backtrace_cleaner.clean(original_exception.backtrace)
else
original_exception.backtrace
end
end
def sub_template_message
if @sub_templates
"Trace of template inclusion: " +
@ -87,29 +80,16 @@ def line_number
@line_number ||=
if file_name
regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
$1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
$1 if message =~ regexp || backtrace.find { |line| line =~ regexp }
end
end
def to_s
"\n#{self.class} (#{message}) #{source_location}:\n" +
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
end
# don't do anything nontrivial here. Any raised exception from here becomes fatal
# (and can't be rescued).
def backtrace
@backtrace
"\n#{self.class} (#{message}) #{source_location}:\n\n" +
"#{source_extract(4)}\n #{backtrace.join("\n ")}\n\n"
end
private
def compute_backtrace
[
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
clean_backtrace.join("\n ")
]
end
def source_location
if line_number

@ -2,29 +2,28 @@
module Rails
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
ERB_METHOD_SIG = /:in `_run_erb_.*/
APP_DIRS = %w( app config lib test )
APP_DIRS_PATTERN = /^\/?(app|config|lib|test)/
RENDER_TEMPLATE_PATTERN = /:in `_render_template_\w*'/
def initialize
super
add_filter { |line| line.sub("#{Rails.root}/", '') }
add_filter { |line| line.sub(ERB_METHOD_SIG, '') }
add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, '') }
add_filter { |line| line.sub('./', '/') } # for tests
add_gem_filters
add_silencer { |line| !APP_DIRS.any? { |dir| line =~ /^\/?#{dir}/ } }
add_silencer { |line| line !~ APP_DIRS_PATTERN }
end
private
def add_gem_filters
return unless defined? Gem
(Gem.path + [Gem.default_dir]).uniq.each do |path|
# http://gist.github.com/30430
add_filter { |line|
line.sub(%r{(#{path})/gems/([^/]+)-([0-9.]+)/(.*)}, '\2 (\3) \4')
}
end
return unless defined?(Gem)
gems_paths = (Gem.path + [Gem.default_dir]).uniq.map!{ |p| Regexp.escape(p) }
return if gems_paths.empty?
gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w\.]+)/(.*)}
add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') }
end
end