From 7c2ff0288dd627026da52a70cb4bf2e0652b6e24 Mon Sep 17 00:00:00 2001 From: nex3 Date: Sat, 27 Jan 2007 06:34:01 +0000 Subject: [PATCH] More error-throwing infrastructural changes. git-svn-id: svn://hamptoncatlin.com/haml/trunk@309 7063305b-7217-0410-af8c-cdc13e5119b9 --- lib/haml/engine.rb | 47 +++++++++++++++++++++++--------------- lib/haml/template.rb | 20 +++++++--------- test/haml/template_test.rb | 22 ++++-------------- 3 files changed, 42 insertions(+), 47 deletions(-) diff --git a/lib/haml/engine.rb b/lib/haml/engine.rb index 17ad73cb..e348b1eb 100644 --- a/lib/haml/engine.rb +++ b/lib/haml/engine.rb @@ -27,10 +27,18 @@ module Haml def add_backtrace_entry(lineno, filename = nil) # :nodoc: @haml_line = lineno @haml_filename = filename - backtrace.unshift "#{filename || '(haml)'}:#{lineno}" + self.backtrace ||= [] + self.backtrace.unshift "#{filename || '(haml)'}:#{lineno}" end end + # SyntaxError is the type of exception thrown when Haml encounters an + # ill-formatted document. + # It's not particularly interesting, except in that it includes Haml::Error. + class SyntaxError < StandardError + include Haml::Error + end + # This is the class where all the parsing and processing of the Haml # template is done. It can be directly used by the user by creating a # new instance and calling to_html to render the template. For example: @@ -169,9 +177,13 @@ module Haml # flattened block. -1 signifies that there is no such block. @flat_spaces = -1 - # Only do the first round of pre-compiling if we really need to. - # They might be passing in the precompiled string. - do_precompile if @precompiled.nil? && (@precompiled = String.new) + begin + # Only do the first round of pre-compiling if we really need to. + # They might be passing in the precompiled string. + do_precompile if @precompiled.nil? && (@precompiled = String.new) + rescue Haml::SyntaxError => e + e.add_backtrace_entry(@index, @options[:filename]) + end end # Processes the template and returns the result as a string. @@ -302,9 +314,17 @@ module Haml push_text line end when ESCAPE - push_text line[1..-1] + if block_opened + raise SyntaxError.new("Illegal Nesting: Nesting within plain text is illegal.") + else + push_text line[1..-1] + end else - push_text line + if block_opened + raise SyntaxError.new("Illegal Nesting: Nesting within plain text is illegal.") + else + push_text line + end end end @@ -375,20 +395,11 @@ module Haml include Haml::Error end + lineno = @scope_object.haml_lineno + # Get information from the exception and format it so that # Rails can understand it. compile_error = e.message.scan(/\(eval\):([0-9]*):in `[-_a-zA-Z]*': compile error/)[0] - filename = nil - if @scope_object.respond_to? :haml_filename - # For some reason that I can't figure out, - # @scope_object.methods.include? "haml_filename" && @scope_object.haml_filename - # is false when it shouldn't be. Nested if statements work, though. - - if @scope_object.haml_filename - filename = "#{@scope_object.haml_filename}.haml" - end - end - lineno = @scope_object.haml_lineno if compile_error eval_line = compile_error[0].to_i @@ -396,7 +407,7 @@ module Haml lineno = line_marker.scan(/[0-9]+/)[0].to_i if line_marker end - e.add_backtrace_entry(lineno, filename) + e.add_backtrace_entry(lineno, @options[:filename]) raise e end diff --git a/lib/haml/template.rb b/lib/haml/template.rb index bb86f454..b1cf482b 100644 --- a/lib/haml/template.rb +++ b/lib/haml/template.rb @@ -58,12 +58,15 @@ module Haml if @view.haml_inline engine = Haml::Engine.new(template, options) - elsif @precompiled = get_precompiled(template) - options[:precompiled] ||= @precompiled - engine = Haml::Engine.new("", options) else - engine = Haml::Engine.new(File.read(template), options) - set_precompiled(template, engine.precompiled) + options[:filename] ||= template + if @precompiled = get_precompiled(template) + options[:precompiled] ||= @precompiled + engine = Haml::Engine.new("", options) + else + engine = Haml::Engine.new(File.read(template), options) + set_precompiled(template, engine.precompiled) + end end yield_proc = @view.instance_eval do @@ -101,15 +104,8 @@ end # here[http://rubyonrails.org/api/classes/ActionView/Base.html]. module ActionView class Base # :nodoc: - attr :haml_filename, true attr :haml_inline - alias_method :haml_old_render_file, :render_file - def render_file(template_path, use_full_path = true, local_assigns = {}) - @haml_filename = File.basename(template_path) - haml_old_render_file(template_path, use_full_path, local_assigns) - end - alias_method :read_template_file_old, :read_template_file def read_template_file(template_path, extension) if extension =~ /haml/i diff --git a/test/haml/template_test.rb b/test/haml/template_test.rb index a642aa1f..fc7cfdae 100644 --- a/test/haml/template_test.rb +++ b/test/haml/template_test.rb @@ -111,28 +111,16 @@ class TemplateTest < Test::Unit::TestCase end def test_exceptions_should_work_correctly - template = < e - assert_equal("(test).haml:4", e.backtrace[0]) + assert_equal("./test/haml/templates/breakage.haml:4", e.backtrace[0]) end - @base.haml_filename = nil begin - render(template.chomp) + render("- raise 'oops!'") rescue Exception => e - assert_equal("(haml):4", e.backtrace[0]) + assert_equal("(haml):1", e.backtrace[0]) end template = <