Skip to content

Commit 22d1dd7

Browse files
authored
Make ErrorHighlight.spot accept Exception (#25)
... and move things from core_ext.rb to base.rb. This will confine CRuby-dependent things to ErrorHighlight.spot.
1 parent 671b7c6 commit 22d1dd7

File tree

3 files changed

+55
-38
lines changed

3 files changed

+55
-38
lines changed

lib/error_highlight/base.rb

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
require_relative "version"
22

33
module ErrorHighlight
4-
# Identify the code fragment that seems associated with a given error
4+
# Identify the code fragment at that a given exception occurred.
55
#
6-
# Arguments:
7-
# node: RubyVM::AbstractSyntaxTree::Node (script_lines should be enabled)
8-
# point_type: :name | :args
9-
# name: The name associated with the NameError/NoMethodError
6+
# Options:
7+
#
8+
# point_type: :name | :args
9+
# :name (default) points the method/variable name that the exception occurred.
10+
# :args points the arguments of the method call that the exception occurred.
11+
#
12+
# backtrace_location: Thread::Backtrace::Location
13+
# It locates the code fragment of the given backtrace_location.
14+
# By default, it uses the first frame of backtrace_locations of the given exception.
1015
#
1116
# Returns:
1217
# {
@@ -15,9 +20,47 @@ module ErrorHighlight
1520
# last_lineno: Integer,
1621
# last_column: Integer,
1722
# snippet: String,
23+
# script_lines: [String],
1824
# } | nil
19-
def self.spot(...)
20-
Spotter.new(...).spot
25+
def self.spot(obj, **opts)
26+
case obj
27+
when Exception
28+
exc = obj
29+
opts = { point_type: opts.fetch(:point_type, :name) }
30+
31+
loc = opts[:backtrace_location]
32+
unless loc
33+
case exc
34+
when TypeError, ArgumentError
35+
opts[:point_type] = :args
36+
end
37+
38+
locs = exc.backtrace_locations
39+
return nil unless locs
40+
41+
loc = locs.first
42+
return nil unless loc
43+
44+
opts[:name] = exc.name if NameError === obj
45+
end
46+
47+
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
48+
49+
Spotter.new(node, **opts).spot
50+
51+
when RubyVM::AbstractSyntaxTree::Node
52+
# Just for compatibility
53+
Spotter.new(node, **opts).spot
54+
55+
else
56+
raise TypeError, "Exception is expected"
57+
end
58+
59+
rescue SyntaxError,
60+
SystemCallError, # file not found or something
61+
ArgumentError # eval'ed code
62+
63+
return nil
2164
end
2265

2366
class Spotter
@@ -122,6 +165,7 @@ def spot
122165
last_lineno: @end_lineno,
123166
last_column: @end_column,
124167
snippet: @snippet,
168+
script_lines: @node.script_lines,
125169
}
126170
else
127171
return nil

lib/error_highlight/core_ext.rb

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,9 @@
33
module ErrorHighlight
44
module CoreExt
55
private def generate_snippet
6-
locs = backtrace_locations
7-
return "" unless locs
8-
9-
loc = locs.first
10-
return "" unless loc
11-
12-
begin
13-
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
14-
opts = {}
15-
16-
case self
17-
when NoMethodError, NameError
18-
opts[:point_type] = :name
19-
opts[:name] = name
20-
when TypeError, ArgumentError
21-
opts[:point_type] = :args
22-
end
23-
24-
spot = ErrorHighlight.spot(node, **opts)
25-
26-
rescue SyntaxError
27-
rescue SystemCallError # file not found or something
28-
rescue ArgumentError # eval'ed code
29-
end
30-
31-
if spot
32-
return ErrorHighlight.formatter.message_for(spot)
33-
end
34-
35-
""
6+
spot = ErrorHighlight.spot(self)
7+
return "" unless spot
8+
return ErrorHighlight.formatter.message_for(spot)
369
end
3710

3811
if Exception.method_defined?(:detailed_message)

test/test_error_highlight.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ def v.foo; 1; end
11501150
def test_custom_formatter
11511151
custom_formatter = Object.new
11521152
def custom_formatter.message_for(spot)
1153-
"\n\n" + spot.inspect
1153+
"\n\n" + spot.except(:script_lines).inspect
11541154
end
11551155

11561156
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter

0 commit comments

Comments
 (0)