aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/template_error.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
commitdb045dbbf60b53dbe013ef25554fd013baf88134 (patch)
tree257830e3c76458c8ff3d1329de83f32b23926028 /actionpack/lib/action_view/template_error.rb
downloadrails-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.rb84
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