diff --git a/lib/sassc/error.rb b/lib/sassc/error.rb index c508c8d9..aef8d075 100644 --- a/lib/sassc/error.rb +++ b/lib/sassc/error.rb @@ -1,9 +1,30 @@ +require 'pathname' require 'sass/error' module SassC class BaseError < StandardError; end - class SyntaxError < BaseError; end class NotRenderedError < BaseError; end class InvalidStyleError < BaseError; end class UnsupportedValue < BaseError; end + + # When dealing with SyntaxErrors, + # it's important to provide filename and line number information. + # This will be used in various error reports to users, including backtraces; + class SyntaxError < BaseError + # The backtrace of the error within Sass files. + attr_accessor :sass_backtrace + + def backtrace + return nil if super.nil? + sass_backtrace + super + end + + def sass_backtrace + line_info = message.split("\n")[1] + return [] unless line_info + + _, line, filename = line_info.match(/on line (\d+) of (.+)/).to_a + ["#{Pathname.getwd.join(filename)}:#{line}"] + end + end end diff --git a/test/error_test.rb b/test/error_test.rb new file mode 100644 index 00000000..7936868d --- /dev/null +++ b/test/error_test.rb @@ -0,0 +1,23 @@ +require_relative "test_helper" + +module SassC + class ErrorTest < MiniTest::Test + def test_first_backtrace_is_sass + line = 2 + filename = "app/assets/stylesheets/application.scss" + + begin + raise SassC::SyntaxError.new(<<-ERROR) +Error: property \"padding\" must be followed by a ':' + on line #{line} of #{filename} +>> padding top: 10px; + --^ + ERROR + rescue SassC::SyntaxError => err + expected = "#{Pathname.getwd.join(filename)}:#{line}" + assert_equal expected, + err.backtrace.first + end + end + end +end