2 # The TemplateError exception is raised when the compilation of the template fails. This exception then gathers a
3 # bunch of intimate details and uses it to report a very precise exception message.
4 class TemplateError
< ActionViewError
#:nodoc:
7 attr_reader
:original_exception
9 def initialize(template
, assigns
, original_exception
)
10 @template, @assigns, @original_exception = template
, assigns
.dup
, original_exception
11 @backtrace = compute_backtrace
15 @template.relative_path
19 ActiveSupport
::Deprecation.silence
{ original_exception
.message
}
23 original_exception
.clean_backtrace
26 def sub_template_message
28 "Trace of template inclusion: " +
29 @sub_templates.collect
{ |template
| template
.relative_path
}.join(", ")
35 def source_extract(indentation
= 0)
36 return unless num
= line_number
39 source_code
= @template.source
.split("\n")
41 start_on_line
= [ num
- SOURCE_CODE_RADIUS
- 1, 0 ].max
42 end_on_line
= [ num
+ SOURCE_CODE_RADIUS
- 1, source_code
.length
].min
44 indent
= ' ' * indentation
45 line_counter
= start_on_line
46 return unless source_code
= source_code
[start_on_line
..end_on_line
]
48 source_code
.sum
do |line
|
50 "#{indent}#{line_counter}: #{line}\n"
54 def sub_template_of(template_path
)
56 @sub_templates << template_path
62 regexp
= /#{Regexp.escape File.basename(file_name)}:(\d+)/
64 $1 if message
=~ regexp
or clean_backtrace
.find
{ |line
| line
=~ regexp
}
69 "\n\n#{self.class} (#{message}) #{source_location}:\n" +
70 "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
73 # don't do anything nontrivial here. Any raised exception from here becomes fatal
74 # (and can't be rescued).
82 "#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
83 clean_backtrace
.join("\n ")
89 "on line ##{line_number} of "
97 if defined?(Exception
::TraceSubstitutions)
98 Exception
::TraceSubstitutions << [/:in\s+`_run_.*'\s*$/, '']
99 Exception
::TraceSubstitutions << [%r
{^\s
*#{Regexp.escape RAILS_ROOT}/}, ''] if defined?(RAILS_ROOT)