Class: Sus::Output::Backtrace

Inherits:
Object
  • Object
show all
Defined in:
lib/sus/output/backtrace.rb

Overview

Represents a backtrace for displaying error locations.

Defined Under Namespace

Classes: Location

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stack, root = nil, limit = nil) ⇒ Backtrace

Initialize a new Backtrace.



50
51
52
53
54
# File 'lib/sus/output/backtrace.rb', line 50

def initialize(stack, root = nil, limit = nil)
	@stack = stack
	@root = root
	@limit = limit
end

Instance Attribute Details

#limitObject (readonly)

Returns the value of attribute limit.



63
64
65
# File 'lib/sus/output/backtrace.rb', line 63

def limit
  @limit
end

#rootObject (readonly)

Returns the value of attribute root.



60
61
62
# File 'lib/sus/output/backtrace.rb', line 60

def root
  @root
end

#stackObject (readonly)

Returns the value of attribute stack.



57
58
59
# File 'lib/sus/output/backtrace.rb', line 57

def stack
  @stack
end

#The limit on the number of frames.(limitonthenumberofframes.) ⇒ Object (readonly)



63
# File 'lib/sus/output/backtrace.rb', line 63

attr :limit

#The root path to filter by.(rootpathtofilterby.) ⇒ Object (readonly)



60
# File 'lib/sus/output/backtrace.rb', line 60

attr :root

#The stack trace locations.(stacktracelocations.) ⇒ Object (readonly)



57
# File 'lib/sus/output/backtrace.rb', line 57

attr :stack

Class Method Details

.extract_stack(exception) ⇒ Object

Extract the stack trace from an exception.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/sus/output/backtrace.rb', line 34

def self.extract_stack(exception)
	if stack = exception.backtrace_locations
		return stack
	elsif stack = exception.backtrace
		return stack.map do |line|
			Location.new(*line.split(":", 3))
		end
	else
		[]
	end
end

.first(identity = nil) ⇒ Object

Create a backtrace from the first caller location.



13
14
15
16
# File 'lib/sus/output/backtrace.rb', line 13

def self.first(identity = nil)
	# This implementation could be a little more efficient.
	self.new(caller_locations(1), identity&.path, 1)
end

.for(exception, identity = nil) ⇒ Object

Create a backtrace from an exception.



22
23
24
25
26
# File 'lib/sus/output/backtrace.rb', line 22

def self.for(exception, identity = nil)
	# I've disabled the root filter here, because partial backtraces are not very useful.
	# We might want to do something to improve presentation of the backtrace based on the root instead.
	self.new(extract_stack(exception), identity&.path)
end

Instance Method Details

#filter(root: @root, limit: @limit) ⇒ Object

Filter the backtrace by root path and limit.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/sus/output/backtrace.rb', line 69

def filter(root: @root, limit: @limit)
	if root
		if limit
			return @stack.lazy.select do |frame|
				frame.path.start_with?(root)
			end.first(limit)
		else
			return up_to_and_matching(@stack) do |frame|
				frame.path.start_with?(root)
			end
		end
	elsif limit
		return @stack.first(limit)
	else
		return @stack
	end
end

Print the backtrace to the output.



89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sus/output/backtrace.rb', line 89

def print(output)
	if @limit == 1
		filter.each do |frame|
			output.write " ", :path, frame.path, :line, ":", frame.lineno
		end
	else
		output.indented do
			filter.each do |frame|
				output.puts :indent, :path, frame.path, :line, ":", frame.lineno, :reset, " ", frame.label
			end
		end
	end
end