diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2004-11-24 01:04:44 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2004-11-24 01:04:44 +0000 |
commit | db045dbbf60b53dbe013ef25554fd013baf88134 (patch) | |
tree | 257830e3c76458c8ff3d1329de83f32b23926028 /actionpack/lib/action_view/template_error.rb | |
download | rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.gz rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.bz2 rails-db045dbbf60b53dbe013ef25554fd013baf88134.zip |
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_view/template_error.rb')
-rw-r--r-- | actionpack/lib/action_view/template_error.rb | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/actionpack/lib/action_view/template_error.rb b/actionpack/lib/action_view/template_error.rb new file mode 100644 index 0000000000..ab05b3303f --- /dev/null +++ b/actionpack/lib/action_view/template_error.rb @@ -0,0 +1,84 @@ +module ActionView + # The TemplateError 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 TemplateError < ActionViewError #:nodoc: + SOURCE_CODE_RADIUS = 3 + + attr_reader :original_exception + + def initialize(base_path, file_name, assigns, source, original_exception) + @base_path, @file_name, @assigns, @source, @original_exception = + base_path, file_name, assigns, source, original_exception + end + + def message + if original_exception.message.include?("(eval):") + original_exception.message.scan(/\(eval\):(?:[0-9]*):in `.*'(.*)/).first.first + else + original_exception.message + end + end + + def sub_template_message + if @sub_templates + "Trace of template inclusion: " + + @sub_templates.collect { |template| strip_base_path(template) }.join(", ") + else + "" + end + end + + def source_extract + source_code = IO.readlines(@file_name) + + start_on_line = [ line_number - SOURCE_CODE_RADIUS - 1, 0 ].max + end_on_line = [ line_number + SOURCE_CODE_RADIUS - 1, source_code.length].min + + line_counter = start_on_line + extract = source_code[start_on_line..end_on_line].collect do |line| + line_counter += 1 + "#{line_counter}: " + line + end + + extract.join + end + + def sub_template_of(file_name) + @sub_templates ||= [] + @sub_templates << file_name + end + + def line_number + begin + @original_exception.backtrace.join.scan(/\((?:erb)\):([0-9]*)/).first.first.to_i + rescue + begin + original_exception.message.scan(/\((?:eval)\):([0-9]*)/).first.first.to_i + rescue + 1 + end + end + end + + def file_name + strip_base_path(@file_name) + end + + def to_s + "\n\n#{self.class} (#{message}) on line ##{line_number} of #{file_name}:\n" + + source_extract + "\n " + + clean_backtrace(original_exception).join("\n ") + + "\n\n" + end + + private + def strip_base_path(file_name) + file_name.gsub(@base_path, "") + end + + def clean_backtrace(exception) + base_dir = File.expand_path(File.dirname(__FILE__) + "/../../../../") + exception.backtrace.collect { |line| line.gsub(base_dir, "").gsub("/public/../config/environments/../../", "").gsub("/public/../", "") } + end + end +end
\ No newline at end of file |