class Mmtrix::NoticedError

This class encapsulates an error that was noticed by Mmtrix in a managed app.

Constants

AGENT_ATTRIBUTES
DESTINATION
EMPTY_HASH
INTRINSIC_ATTRIBUTES
STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE
USER_ATTRIBUTES

Attributes

attributes[RW]
attributes_from_notice_error[RW]
exception_class_name[RW]
exception_id[R]
file_name[RW]
is_internal[R]
line_number[RW]
message[RW]
path[RW]
request_uri[RW]
stack_trace[RW]
timestamp[RW]

Public Class Methods

new(path, exception, timestamp = Time.now) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 20
def initialize(path, exception, timestamp = Time.now)
  @exception_id = exception.object_id
  @path = path
  @exception_class_name = exception.is_a?(Exception) ? exception.class.name : 'Error'

  # It's critical that we not hold onto the exception class constant in this
  # class. These objects get serialized for Resque to a process that might
  # not have the original exception class loaded, so do all processing now
  # while we have the actual exception!
  @is_internal = (exception.class < Mmtrix::Agent::InternalAgentError)

  if exception.nil?
    @message = '<no message>'
  elsif exception.respond_to?('original_exception')
    @message = (exception.original_exception || exception).to_s
  else # exception is not nil, but does not respond to original_exception
    @message = exception.to_s
  end


  unless @message.is_a?(String)
    # In pre-1.9.3, Exception.new({}).to_s.class != String
    # That is, Exception#to_s may not return a String instance if one wasn't
    # passed in upon creation of the Exception. So, try to generate a useful
    # String representation of the exception message, falling back to failsafe
    @message = String(@message.inspect) rescue '<unknown message type>'
  end

  # clamp long messages to 4k so that we don't send a lot of
  # overhead across the wire
  @message = @message[0..4095] if @message.length > 4096

  # replace error message if enabled
  if Mmtrix::Agent.config[:'strip_exception_messages.enabled'] &&
     !self.class.passes_message_whitelist(exception.class)
    @message = STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE
  end

  @timestamp = timestamp
end
passes_message_whitelist(exception_class) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 76
def self.passes_message_whitelist(exception_class)
  Mmtrix::Agent.config[:'strip_exception_messages.whitelist'].any? do |klass|
    exception_class <= klass
  end
end

Public Instance Methods

==(other) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 68
def ==(other)
  if other.respond_to?(:exception_id)
    exception_id == other.exception_id
  else
    false
  end
end
append_attributes(outgoing_params, outgoing_key, source_attributes) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 160
def append_attributes(outgoing_params, outgoing_key, source_attributes)
  outgoing_params[outgoing_key] = source_attributes || {}
end
base_parameters() click to toggle source
# File lib/mmtrix/noticed_error.rb, line 108
def base_parameters
  params = {}
  params[:request_uri] = request_uri if request_uri
  params[:file_name]   = file_name   if file_name
  params[:line_number] = line_number if line_number
  params[:stack_trace] = stack_trace if stack_trace
  params
end
build_agent_attributes() click to toggle source
# File lib/mmtrix/noticed_error.rb, line 144
def build_agent_attributes
  if @attributes
    @attributes.agent_attributes_for(DESTINATION)
  else
    EMPTY_HASH
  end
end
build_intrinsic_attributes() click to toggle source
# File lib/mmtrix/noticed_error.rb, line 152
def build_intrinsic_attributes
  if @attributes
    @attributes.intrinsic_attributes_for(DESTINATION)
  else
    EMPTY_HASH
  end
end
build_params() click to toggle source
# File lib/mmtrix/noticed_error.rb, line 100
def build_params
  params = base_parameters
  append_attributes(params, USER_ATTRIBUTES, merged_custom_attributes)
  append_attributes(params, AGENT_ATTRIBUTES, build_agent_attributes)
  append_attributes(params, INTRINSIC_ATTRIBUTES, build_intrinsic_attributes)
  params
end
exception_class() click to toggle source

@exception_class has been deprecated in favor of the more descriptive @exception_class_name. @deprecated

# File lib/mmtrix/noticed_error.rb, line 64
def exception_class
  exception_class_name
end
merge_custom_attributes_from_notice_error(merged_attributes) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 137
def merge_custom_attributes_from_notice_error(merged_attributes)
  if @attributes_from_notice_error
    from_notice_error = Mmtrix::NoticedError.normalize_params(@attributes_from_notice_error)
    merged_attributes.merge_custom_attributes(from_notice_error)
  end
end
merge_custom_attributes_from_transaction(merged_attributes) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 130
def merge_custom_attributes_from_transaction(merged_attributes)
  if @attributes
    from_transaction = @attributes.custom_attributes_for(DESTINATION)
    merged_attributes.merge_custom_attributes(from_transaction)
  end
end
merged_custom_attributes() click to toggle source

We can get custom attributes from two sources–the transaction, which we hold in @attributes, or passed options to notice_error which show up in @attributes_from_notice_error. Both need filtering, so merge them together in our Attributes class for consistent handling

# File lib/mmtrix/noticed_error.rb, line 121
def merged_custom_attributes
  merged_attributes = Mmtrix::Agent::Transaction::Attributes.new(Mmtrix::Agent.instance.attribute_filter)

  merge_custom_attributes_from_transaction(merged_attributes)
  merge_custom_attributes_from_notice_error(merged_attributes)

  merged_attributes.custom_attributes_for(DESTINATION)
end
to_collector_array(encoder=nil) click to toggle source
# File lib/mmtrix/noticed_error.rb, line 84
def to_collector_array(encoder=nil)
  [ Mmtrix::Helper.time_to_millis(timestamp),
    string(path),
    string(message),
    string(exception_class_name),
    build_params ]
end