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 if defined?(Rails
) && Rails
.respond_to
?(:backtrace_cleaner)
24 Rails
.backtrace_cleaner
.clean(original_exception
.backtrace
)
26 original_exception
.backtrace
30 def sub_template_message
32 "Trace of template inclusion: " +
33 @sub_templates.collect
{ |template
| template
.relative_path
}.join(", ")
39 def source_extract(indentation
= 0)
40 return unless num
= line_number
43 source_code
= @template.source
.split("\n")
45 start_on_line
= [ num
- SOURCE_CODE_RADIUS
- 1, 0 ].max
46 end_on_line
= [ num
+ SOURCE_CODE_RADIUS
- 1, source_code
.length
].min
48 indent
= ' ' * indentation
49 line_counter
= start_on_line
50 return unless source_code
= source_code
[start_on_line
..end_on_line
]
52 source_code
.sum
do |line
|
54 "#{indent}#{line_counter}: #{line}\n"
58 def sub_template_of(template_path
)
60 @sub_templates << template_path
66 regexp
= /#{Regexp.escape File.basename(file_name)}:(\d+)/
68 $1 if message
=~ regexp
or clean_backtrace
.find
{ |line
| line
=~ regexp
}
73 "\n#{self.class} (#{message}) #{source_location}:\n" +
74 "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
77 # don't do anything nontrivial here. Any raised exception from here becomes fatal
78 # (and can't be rescued).
86 "#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
87 clean_backtrace
.join("\n ")
93 "on line ##{line_number} of "