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.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/traject/util.rb', line 84

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.



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
74
75
76
# File 'lib/traject/util.rb', line 43

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
        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.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/traject/util.rb', line 116

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, but let's
    # stop iterating and return what we've got.
    return result
  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
20
21
22
23
24
25
26
# 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"

  caused_by = e.cause
  # JRuby Java exception might have getRootCause
  if caused_by == nil && e.respond_to?(:getRootCause) && e.getRootCause
    caused_by = e.getRootCause
  end
  if caused_by == e
    caused_by = nil
  end
  if caused_by
    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.



30
31
32
# File 'lib/traject/util.rb', line 30

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

.io_name(io_like_object) ⇒ Object

How can we refer to an io object input in logs? For now, if it's a file-like object, we can use #path.



141
142
143
# File 'lib/traject/util.rb', line 141

def self.io_name(io_like_object)
  io_like_object.path if io_like_object.respond_to?(:path)
end

.is_jruby?Boolean

Returns:

  • (Boolean)


133
134
135
136
137
138
# File 'lib/traject/util.rb', line 133

def self.is_jruby?
  unless defined?(@is_jruby)
    @is_jruby = defined?(JRUBY_VERSION)
  end
  @is_jruby
end