module NdrError::BacktraceCompression

Mixin to help compressing/expanding stored backtraces.

Public Instance Methods

application_trace() click to toggle source

Attempts to return just the “application” trace, so we can highlight “our” code vs. 3rd-party libraries.

# File lib/ndr_error/backtrace_compression.rb, line 6
def application_trace
  app_trace = backtrace.select do |line|
    app = line =~ %r{/(#{Rails.root.basename}|current|releases)/}
    ndr = line =~ %r{/gems/ndr_}

    app || ndr
  end

  app_trace = backtrace.reject { |line| line =~ %r{/gems/} } if app_trace.blank?
  app_trace
end
backtrace() click to toggle source

Returns the backtrace as an array.

# File lib/ndr_error/backtrace_compression.rb, line 19
def backtrace
  inflate_backtrace(lines)
end
backtrace=(trace) click to toggle source

Stores as much of the backtrace as is possible in a string. Splits out any nested lines, e.g. TemplateError backtrace.

# File lib/ndr_error/backtrace_compression.rb, line 25
def backtrace=(trace)
  array = trace ? trace.dup : []
  array = array.map { |line| line.split("\n") }.flatten
  dump  = deflate_backtrace(array)

  while dump.length >= 4000
    array.pop
    dump = deflate_backtrace(array)
  end

  self.lines = dump
end

Private Instance Methods

deflate_backtrace(lines) click to toggle source

Type conversion helper, so backtrace can be assigned as an array and saved as a string. If compression is enabled, this method will compress the string too.

# File lib/ndr_error/backtrace_compression.rb, line 62
def deflate_backtrace(lines)
  string = lines.join("\n")

  if NdrError.compress_backtrace
    data   = Zlib::Deflate.deflate(string)
    string = Base64.encode64(data)
  end

  string
end
inflate_backtrace(data) click to toggle source

Helper for wrapping the lines column, enables the backtrace to be returned as an array rather that as the stored string. If compression is enabled, will decompress the string before returing the array.

# File lib/ndr_error/backtrace_compression.rb, line 44
def inflate_backtrace(data)
  string = data || ''

  if NdrError.compress_backtrace
    data = Base64.decode64(string)
    begin
      string = Zlib::Inflate.inflate(data)
    rescue StandardError
      Rails.logger.warn('NdrError: failed to inflate backtrace!')
    end
  end

  string.split("\n")
end