module Airbrake::Backtrace

def self.java_exception?(exception)

Returns:
  • (Boolean) -

Parameters:
  • exception (Exception) --
def self.java_exception?(exception)
  if defined?(Java::JavaLang::Throwable) &&
     exception.is_a?(Java::JavaLang::Throwable)
    return true
  end
  return false unless exception.respond_to?(:backtrace)
  (Patterns::JAVA =~ exception.backtrace.first) != nil
end

def self.parse(exception)

Returns:
  • (ArrayString,Integer}>) - the parsed backtrace

Parameters:
  • exception (Exception) -- The exception, which contains a backtrace to
def self.parse(exception)
  return [] if exception.backtrace.nil? || exception.backtrace.none?
  parse_backtrace(exception)
end

def best_regexp_for(exception)

def best_regexp_for(exception)
  if java_exception?(exception)
    Patterns::JAVA
  elsif oci_exception?(exception)
    Patterns::OCI
  elsif execjs_exception?(exception)
    Patterns::EXECJS
  else
    Patterns::RUBY
  end
end

def execjs_exception?(exception)

def execjs_exception?(exception)
  return false unless defined?(ExecJS::RuntimeError)
  return true if exception.is_a?(ExecJS::RuntimeError)
  return true if exception.cause && exception.cause.is_a?(ExecJS::RuntimeError)
  false
end

def frame_in_root?(frame, root_directory)

def frame_in_root?(frame, root_directory)
  frame[:file].start_with?(root_directory) && frame[:file] !~ %r{vendor/bundle}
end

def match_frame(regexp, stackframe)

def match_frame(regexp, stackframe)
  match = regexp.match(stackframe)
  return match if match
  Patterns::GENERIC.match(stackframe)
end

def oci_exception?(exception)

def oci_exception?(exception)
  defined?(OCIError) && exception.is_a?(OCIError)
end

def parse_backtrace(exception)

def parse_backtrace(exception)
  regexp = best_regexp_for(exception)
  root_directory = Airbrake::Config.instance.root_directory.to_s
  exception.backtrace.map.with_index do |stackframe, i|
    frame = stack_frame(regexp, stackframe)
    next(frame) if !Airbrake::Config.instance.code_hunks || frame[:file].nil?
    if !root_directory.empty?
      populate_code(frame) if frame_in_root?(frame, root_directory)
    elsif i < CODE_FRAME_LIMIT
      populate_code(frame)
    end
    frame
  end
end

def populate_code(frame)

def populate_code(frame)
  code = Airbrake::CodeHunk.new.get(frame[:file], frame[:line])
  frame[:code] = code if code
end

def stack_frame(regexp, stackframe)

def stack_frame(regexp, stackframe)
  if (match = match_frame(regexp, stackframe))
    return {
      file: match[:file],
      line: (Integer(match[:line]) if match[:line]),
      function: match[:function],
    }
  end
  logger.error(
    "can't parse '#{stackframe}' (please file an issue so we can fix " \
    "it: https://github.com/airbrake/airbrake-ruby/issues/new)",
  )
  { file: nil, line: nil, function: stackframe }
end