1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

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

View file

@ -21,17 +21,18 @@ module ActionView
super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}") super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}")
end end
end end
class Template class Template
# The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a # 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. # bunch of intimate details and uses it to report a very precise exception message.
class Error < ActionViewError #:nodoc: class Error < ActionViewError #:nodoc:
SOURCE_CODE_RADIUS = 3 SOURCE_CODE_RADIUS = 3
attr_reader :original_exception attr_reader :original_exception, :backtrace
def initialize(template, assigns, original_exception) def initialize(template, assigns, original_exception)
@template, @assigns, @original_exception = template, assigns.dup, original_exception @template, @assigns, @original_exception = template, assigns.dup, original_exception
@backtrace = compute_backtrace @backtrace = original_exception.backtrace
end end
def file_name def file_name
@ -42,14 +43,6 @@ module ActionView
ActiveSupport::Deprecation.silence { original_exception.message } ActiveSupport::Deprecation.silence { original_exception.message }
end 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 def sub_template_message
if @sub_templates if @sub_templates
"Trace of template inclusion: " + "Trace of template inclusion: " +
@ -87,29 +80,16 @@ module ActionView
@line_number ||= @line_number ||=
if file_name if file_name
regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/ regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
$1 if message =~ regexp || backtrace.find { |line| line =~ regexp }
$1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
end end
end end
def to_s def to_s
"\n#{self.class} (#{message}) #{source_location}:\n" + "\n#{self.class} (#{message}) #{source_location}:\n\n" +
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n" "#{source_extract(4)}\n #{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
end end
private private
def compute_backtrace
[
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
clean_backtrace.join("\n ")
]
end
def source_location def source_location
if line_number if line_number

View file

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