class Datadog::Error

Error is a value-object responsible for sanitizing/encapsulating error data

Constants

BlankError
ContainsMessage

Attributes

backtrace[R]
message[R]
type[R]

Public Class Methods

build_from(value) click to toggle source
# File lib/ddtrace/error.rb, line 11
def build_from(value)
  case value
  when Error then value
  when Array then new(*value)
  when Exception then new(value.class, value.message, full_backtrace(value))
  when ContainsMessage then new(value.class, value.message)
  else BlankError
  end
end
new(type = nil, message = nil, backtrace = nil) click to toggle source
# File lib/ddtrace/error.rb, line 86
def initialize(type = nil, message = nil, backtrace = nil)
  backtrace = Array(backtrace).join("\n") unless backtrace.is_a?(String)

  @type = Utils.utf8_encode(type)
  @message = Utils.utf8_encode(message)
  @backtrace = Utils.utf8_encode(backtrace)
end

Private Class Methods

backtrace_for(ex, backtrace) click to toggle source

Outputs the following format for exceptions:

“` error_spec.rb:55:in `wrapper': wrapper layer (RuntimeError)

      from error_spec.rb:40:in `wrapper'
      from error_spec.rb:61:in `caller'
...

“`

# File lib/ddtrace/error.rb, line 59
def backtrace_for(ex, backtrace)
  trace = ex.backtrace
  return unless trace

  if trace[0]
    # Add Exception information to error line
    backtrace << trace[0]
    backtrace << ': '
    backtrace << ex.message.to_s
    backtrace << ' ('
    backtrace << ex.class.to_s
    backtrace << ')'
  end

  if trace[1]
    # Ident stack trace for caller lines, to separate
    # them from the main error lines.
    trace[1..-1].each do |line|
      backtrace << "\n\tfrom "
      backtrace << line
    end
  end

  backtrace << "\n"
end
full_backtrace(ex) click to toggle source

Returns a stack trace with nested error causes and details.

This manually implements Ruby >= 2.6 error output for two reasons:

  1. It is not available in Ruby < 2.6.

  2. It's measurably faster to manually implement it in Ruby.

This method mimics the exact output of `ex.full_message(highlight: false, order: :top)` but it's around 3x faster in our benchmark test at `error_spec.rb`.

# File lib/ddtrace/error.rb, line 34
def full_backtrace(ex)
  backtrace = String.new
  backtrace_for(ex, backtrace)

  # Avoid circular causes
  causes = {}
  causes[ex] = true

  cause = ex
  while (cause = cause.cause) && !causes.key?(cause)
    backtrace_for(cause, backtrace)
    causes[cause] = true
  end

  backtrace
end