Module: Traject::Util

Defined in:
lib/traject/util.rb

Overview

Just some internal utility methods

Class Method Summary collapse

Class Method Details

.backtrace_from_config(file_path, exception) ⇒ Object

Extract just the part of the backtrace that is "below" the config file mentioned. If we can't find the config file in the stack trace, we might return empty array.

If the ruby supports Exception#backtrace_locations, the returned array will actually be of Thread::Backtrace::Location elements.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/traject/util.rb', line 78

def self.backtrace_from_config(file_path, exception)
  filtered_trace = []
  found          = false

  # MRI 2.1+ has exception.backtrace_locations which makes
  # this a lot easier, but JRuby 1.7.x doesn't yet, so we
  # need to do it both ways.
  if (exception.respond_to?(:backtrace_locations) &&
      exception.backtrace_locations &&
      exception.backtrace_locations.length > 0)

    exception.backtrace_locations.each do |location|
      filtered_trace << location
      (found=true and break) if location.path == file_path
    end
  else
    filtered_trace = []
    exception.backtrace.each do |line|
      filtered_trace << line
      (found=true and break) if line.start_with?(file_path)
    end
  end

  return found ? filtered_trace : []
end

.backtrace_lineno_for_config(file_path, exception) ⇒ Object

Provide a config source file path, and an exception.

Returns the line number from the first line in the stack trace of the exception that matches your file path. of the first line in the backtrace matching that file_path.

Returns nil if no suitable backtrace line can be found.

Has special logic to try and grep the info out of a SyntaxError, bah.



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
# File 'lib/traject/util.rb', line 36

def self.backtrace_lineno_for_config(file_path, exception)
  # For a SyntaxError, we really need to grep it from the
  # exception message, it really appears to be nowhere else. Ugh.
  if exception.kind_of? SyntaxError
    if m = /:(\d+):/.match(exception.message)
      return m[1].to_i
    end
  end

  # Otherwise we try to fish it out of the backtrace, first
  # line matching the config file path.

  # exception.backtrace_locations exists in MRI 2.1+, which makes
  # our task a lot easier. But not yet in JRuby 1.7.x, so we got to
  # handle the old way of having to parse the strings in backtrace too.
  if (exception.respond_to?(:backtrace_locations) &&
      exception.backtrace_locations &&
      exception.backtrace_locations.length > 0)
    location = exception.backtrace_locations.find do |bt|
      bt.path == file_path
    end
    return location ? location.lineno : nil
  else # have to parse string backtrace
    exception.backtrace.each do |line|
      if line.start_with?(file_path)
        if m = /\A.*\:(\d+)\:in/.match(line)
          return m[1].to_i
          break
        end
      end
    end
    # if we got here, we have nothing
    return nil
  end
end

.drain_queue(queue) ⇒ Object

Ruby stdlib queue lacks a 'drain' function, we write one.

Removes everything currently in the ruby stdlib queue, and returns it an array. Should be concurrent-safe, but queue may still have some things in it after drain, if there are concurrent writers.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/traject/util.rb', line 110

def self.drain_queue(queue)
  result = []

  queue_size = queue.size
  begin
    queue_size.times do
      result << queue.deq(:raise_if_empty)
    end
  rescue ThreadError
    # Need do nothing, queue was concurrently popped, no biggie
  end

  return result
end

.exception_to_log_message(e) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/traject/util.rb', line 5

def self.exception_to_log_message(e)
  indent = "    "

  msg = indent + "Exception: " + e.class.name + ": " + e.message + "\n"
  msg += indent + e.backtrace.first + "\n"

  if (e.respond_to?(:getRootCause) && e.getRootCause && e != e.getRootCause)
    caused_by = e.getRootCause
    msg       += indent + "Caused by\n"
    msg       += indent + caused_by.class.name + ": " + caused_by.message + "\n"
    msg       += indent + caused_by.backtrace.first + "\n"
  end

  return msg
end

.extract_caller_location(str) ⇒ Object

From ruby #caller method, you get an array. Pass one line of the array here, get just file and line number out.



23
24
25
# File 'lib/traject/util.rb', line 23

def self.extract_caller_location(str)
  str.split(':in `').first
end