Module: ErrorHighlight

Defined in:
lib/error_highlight/base.rb,
lib/error_highlight/version.rb,
lib/error_highlight/core_ext.rb,
lib/error_highlight/formatter.rb

Defined Under Namespace

Modules: CoreExt Classes: DefaultFormatter

Constant Summary collapse

VERSION =
"0.6.0"

Class Method Summary collapse

Class Method Details

.formatterObject



16
17
18
# File 'lib/error_highlight/formatter.rb', line 16

def self.formatter
  Ractor.current[:__error_highlight_formatter__] || DefaultFormatter
end

.formatter=(formatter) ⇒ Object



20
21
22
# File 'lib/error_highlight/formatter.rb', line 20

def self.formatter=(formatter)
  Ractor.current[:__error_highlight_formatter__] = formatter
end

.spot(obj, **opts) ⇒ Object

Identify the code fragment at that a given exception occurred.

Options:

point_type: :name | :args

:name (default) points the method/variable name that the exception occurred.
:args points the arguments of the method call that the exception occurred.

backtrace_location: Thread::Backtrace::Location

It locates the code fragment of the given backtrace_location.
By default, it uses the first frame of backtrace_locations of the given exception.

Returns:

{
  first_lineno: Integer,
  first_column: Integer,
  last_lineno: Integer,
  last_column: Integer,
  snippet: String,
  script_lines: [String],
} | nil

Limitations:

Currently, ErrorHighlight.spot only supports a single-line code fragment. Therefore, if the return value is not nil, first_lineno and last_lineno will have the same value. If the relevant code fragment spans multiple lines (e.g., Array#[] of ary), the method will return nil. This restriction may be removed in the future.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/error_highlight/base.rb', line 33

def self.spot(obj, **opts)
  case obj
  when Exception
    exc = obj
    loc = opts[:backtrace_location]
    opts = { point_type: opts.fetch(:point_type, :name) }

    unless loc
      case exc
      when TypeError, ArgumentError
        opts[:point_type] = :args
      end

      locs = exc.backtrace_locations
      return nil unless locs

      loc = locs.first
      return nil unless loc

      opts[:name] = exc.name if NameError === obj
    end

    return nil unless Thread::Backtrace::Location === loc

    node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)

    Spotter.new(node, **opts).spot

  when RubyVM::AbstractSyntaxTree::Node
    Spotter.new(obj, **opts).spot

  else
    raise TypeError, "Exception is expected"
  end

rescue SyntaxError,
       SystemCallError, # file not found or something
       ArgumentError # eval'ed code

  return nil
end