lib/sass/exception.rb
# frozen_string_literal: true module Sass # An exception thrown because a Sass compilation failed. class CompileError < StandardError # @return [String, nil] attr_reader :sass_stack # @return [Logger::SourceSpan, nil] attr_reader :span # @return [Array<String>] attr_reader :loaded_urls # @!visibility private def initialize(message, full_message, sass_stack, span, loaded_urls) super(message) @full_message = full_message @sass_stack = sass_stack @span = span @loaded_urls = loaded_urls end # @return [String] def full_message(highlight: nil, order: nil, **) return super if @full_message.nil? highlight = Exception.to_tty? if highlight.nil? if highlight @full_message.dup else @full_message.gsub(/\e\[[0-9;]*m/, '') end end # @return [String] def to_css content = full_message(highlight: false, order: :top) <<~CSS.freeze /* #{content.gsub('*/', "*\u2060/").gsub("\r\n", "\n").split("\n").join("\n * ")} */ body::before { position: static; display: block; padding: 1em; margin: 0 0 1em; border-width: 0 0 2px; border-bottom-style: solid; font-family: monospace, monospace; white-space: pre; content: #{Serializer.serialize_quoted_string(content).gsub(/[^[:ascii:]][\h\t ]?/) do |match| ordinal = match.ord replacement = "\\#{ordinal.to_s(16)}" if match.length > 1 replacement << ' ' if ordinal < 0x100000 replacement << match[1] end replacement end}; } CSS end end # An exception thrown by Sass Script. class ScriptError < StandardError # @!visibility private def initialize(message, name = nil) super(name.nil? ? message : "$#{name}: #{message}") end end end