class Honeybadger::Notice
Constants
- BACKTRACE_FILTERS
@api private A list of backtrace filters to run all the time.
- GEM_ROOT_CACHE
@api private Cache gem path substitutions for backtrace lines.
- PROJECT_ROOT_CACHE
@api private Cache project path substitutions for backtrace lines.
- TAG_SANITIZER
@api private The Regexp used to strip invalid characters from individual tags.
- TAG_SEPERATOR
@api private The String character used to split tag strings.
Attributes
The action (if any) that was called in this request.
The API key used to deliver this notice.
The backtrace from the given exception or hash.
The exception cause if available.
@return [Cause] A list of exception causes (see {Cause})
CGI variables such as HTTP_METHOD.
The component (if any) which was used in this request (usually the controller).
The context Hash.
The component (if any) which was used in this request (usually the controller).
The component (if any) which was used in this request (usually the controller).
Custom details data
The name of the class of error (example: RuntimeError).
The message from the exception, or a general description of the error.
The exception that caused this notice, if any.
Custom fingerprint for error, used to group similar errors together.
The unique ID of this notice which can be used to reference the error in Honeybadger
.
Local variables are extracted from first frame of backtrace.
A hash of parameters from the query string or post body.
A hash of parameters from the query string or post body.
A hash of session data from the request.
The URL at which the error occurred (if any).
Public Class Methods
@api private
# File lib/honeybadger/notice.rb, line 179 def initialize(config, opts = {}) @now = Time.now.utc @pid = Process.pid @id = SecureRandom.uuid @stats = Util::Stats.all @opts = opts @config = config @rack_env = opts.fetch(:rack_env, nil) @request_sanitizer = Util::Sanitizer.new(filters: params_filters) @exception = unwrap_exception(opts[:exception]) self.error_class = exception_attribute(:error_class, 'Notice') {|exception| exception.class.name } self.error_message = exception_attribute(:error_message, 'No message provided') do |exception| "#{exception.class.name}: #{exception.message}" end self.backtrace = exception_attribute(:backtrace, caller) self.cause = opts.key?(:cause) ? opts[:cause] : (exception_cause(@exception) || $!) self.context = construct_context_hash(opts, exception) self.local_variables = local_variables_from_exception(exception, config) self.api_key = opts[:api_key] || config[:api_key] self.tags = construct_tags(opts[:tags]) | construct_tags(context[:tags]) self.url = opts[:url] || request_hash[:url] || nil self.action = opts[:action] || request_hash[:action] || nil self.component = opts[:controller] || opts[:component] || request_hash[:component] || nil self.params = opts[:parameters] || opts[:params] || request_hash[:params] || {} self.session = opts[:session] || request_hash[:session] || {} self.cgi_data = opts[:cgi_data] || request_hash[:cgi_data] || {} self.details = opts[:details] || {} self.session = opts[:session][:data] if opts[:session] && opts[:session][:data] self.breadcrumbs = opts[:breadcrumbs] || Breadcrumbs::Collector.new(config) # Fingerprint must be calculated last since callback operates on `self`. self.fingerprint = fingerprint_from_opts(opts) end
Public Instance Methods
@api private Template used to create JSON payload.
@return [Hash] JSON representation of notice.
# File lib/honeybadger/notice.rb, line 225 def as_json(*args) request = construct_request_hash request[:context] = s(context) request[:local_variables] = local_variables if local_variables { api_key: s(api_key), notifier: NOTIFIER, breadcrumbs: sanitized_breadcrumbs, error: { token: id, class: s(error_class), message: s(error_message), backtrace: s(parse_backtrace(backtrace)), fingerprint: fingerprint_hash, tags: s(tags), causes: s(prepare_causes(causes)) }, details: s(details), request: request, server: { project_root: s(config[:root]), revision: s(config[:revision]), environment_name: s(config[:env]), hostname: s(config[:hostname]), stats: stats, time: now, pid: pid } } end
# File lib/honeybadger/notice.rb, line 82 def cause=(cause) @cause = cause @causes = unwrap_causes(cause) end
@api private Determines if this notice will be discarded.
# File lib/honeybadger/notice.rb, line 279 def halted? !!@halted end
@api private Determines if this notice should be ignored.
# File lib/honeybadger/notice.rb, line 266 def ignore? ignore_by_origin? || ignore_by_class? || ignore_by_callbacks? end
Converts the notice to JSON.
@return [Hash] The JSON representation of the notice.
# File lib/honeybadger/notice.rb, line 260 def to_json(*a) ::JSON.generate(as_json(*a)) end
Private Instance Methods
# File lib/honeybadger/notice.rb, line 350 def construct_backtrace_filters(opts) [ config.backtrace_filter ].compact | BACKTRACE_FILTERS end
# File lib/honeybadger/notice.rb, line 400 def construct_context_hash(opts, exception) context = {} context.merge!(Context(opts[:global_context])) context.merge!(exception_context(exception)) context.merge!(Context(opts[:context])) context end
Construct the request data.
Returns¶ ↑
Returns Hash request data.
# File lib/honeybadger/notice.rb, line 363 def construct_request_hash request = { url: url, component: component, action: action, params: params, session: session, cgi_data: cgi_data, sanitizer: request_sanitizer } request.delete_if {|k,v| config.excluded_request_keys.include?(k) } Util::RequestPayload.build(request) end
Gets a property named “attribute” of an exception, either from the args hash or actual exception (in order of precidence).
- attribute
-
A Symbol existing as a key in args and/or attribute on Exception.
- default
-
Default value if no other value is found (optional).
- block
-
An optional block which receives an Exception and returns the desired value.
Returns¶ ↑
Returns attribute value from args or exception, otherwise default.
# File lib/honeybadger/notice.rb, line 309 def exception_attribute(attribute, default = nil, &block) opts[attribute] || (exception && from_exception(attribute, &block)) || default end
Fetch cause from exception.
- exception
-
Exception to fetch cause from.
Returns¶ ↑
Returns the Exception cause.
# File lib/honeybadger/notice.rb, line 517 def exception_cause(exception) e = exception if e.respond_to?(:cause) && e.cause && e.cause.is_a?(Exception) e.cause elsif e.respond_to?(:original_exception) && e.original_exception && e.original_exception.is_a?(Exception) e.original_exception elsif e.respond_to?(:continued_exception) && e.continued_exception && e.continued_exception.is_a?(Exception) e.continued_exception end end
Get optional context from exception.
Returns¶ ↑
Returns the Hash context.
# File lib/honeybadger/notice.rb, line 380 def exception_context(exception) # This extra check exists because the exception itself is not expected to # convert to a hash. object = exception if exception.respond_to?(:to_honeybadger_context) object ||= {}.freeze Context(object) end
# File lib/honeybadger/notice.rb, line 408 def fingerprint_from_opts(opts) callback = opts[:fingerprint] callback ||= config.exception_fingerprint if callback.respond_to?(:call) callback.call(self) else callback end end
# File lib/honeybadger/notice.rb, line 419 def fingerprint_hash return unless fingerprint Digest::SHA1.hexdigest(fingerprint.to_s) end
Gets a property named attribute
from an exception.
If a block is given, it will be used when getting the property from an exception. The block should accept and exception and return the value for the property.
If no block is given, a method with the same name as attribute
will be invoked for the value.
# File lib/honeybadger/notice.rb, line 321 def from_exception(attribute) return unless exception if block_given? yield(exception) else exception.send(attribute) end end
# File lib/honeybadger/notice.rb, line 294 def ignore_by_callbacks? config.exception_filter && config.exception_filter.call(self) end
Determines if error class should be ignored.
- ignored_class_name
-
The name of the ignored class. May be a string or regexp (optional).
Returns¶ ↑
Returns true or false.
# File lib/honeybadger/notice.rb, line 337 def ignore_by_class?(ignored_class = nil) @ignore_by_class ||= Proc.new do |ignored_class| case error_class when (ignored_class.respond_to?(:name) ? ignored_class.name : ignored_class) true else exception && ignored_class.is_a?(Class) && exception.class < ignored_class end end ignored_class ? @ignore_by_class.call(ignored_class) : config.ignored_classes.any?(&@ignore_by_class) end
# File lib/honeybadger/notice.rb, line 288 def ignore_by_origin? return false if opts[:origin] != :rake return false if config[:'exceptions.rescue_rake'] true end
Fetch local variables from first frame of backtrace.
- exception
-
The Exception containing the bindings stack.
Returns¶ ↑
Returns a Hash of local variables.
# File lib/honeybadger/notice.rb, line 445 def local_variables_from_exception(exception, config) return nil unless send_local_variables?(config) return {} unless Exception === exception return {} unless exception.respond_to?(:__honeybadger_bindings_stack) return {} if exception.__honeybadger_bindings_stack.empty? if config[:root] binding = exception.__honeybadger_bindings_stack.find { |b| if BINDING_HAS_SOURCE_LOCATION b.source_location[0] else b.eval('__FILE__') end =~ /^#{Regexp.escape(config[:root].to_s)}/ } end binding ||= exception.__honeybadger_bindings_stack[0] vars = binding.eval('local_variables') results = vars.inject([]) { |acc, arg| begin result = binding.eval(arg.to_s) acc << [arg, result] rescue NameError # Do Nothing end acc } result_hash = Hash[results] request_sanitizer.sanitize(result_hash) end
# File lib/honeybadger/notice.rb, line 560 def params_filters config.params_filters + rails_params_filters end
Parse Backtrace
from exception backtrace.
- backtrace
-
The Array backtrace from exception.
Returns¶ ↑
Returns the Backtrace
.
# File lib/honeybadger/notice.rb, line 492 def parse_backtrace(backtrace) Backtrace.parse( backtrace, filters: construct_backtrace_filters(opts), config: config, source_radius: config[:'exceptions.source_radius'] ).to_a end
Convert list of causes into payload format.
- causes
-
Array of
Cause
instances.
Returns¶ ↑
Returns the Array of causes in Hash payload format.
# File lib/honeybadger/notice.rb, line 550 def prepare_causes(causes) causes.map {|c| { class: c.error_class, message: c.error_message, backtrace: parse_backtrace(c.backtrace) } } end
# File lib/honeybadger/notice.rb, line 564 def rails_params_filters rack_env && Array(rack_env['action_dispatch.parameter_filter']) or [] end
# File lib/honeybadger/notice.rb, line 356 def request_hash @request_hash ||= Util::RequestHash.from_env(rack_env) end
# File lib/honeybadger/notice.rb, line 436 def s(data) Util::Sanitizer.sanitize(data) end
Create a list of causes.
- cause
-
The first cause to unwrap.
Returns¶ ↑
Returns the Array of Cause
instances.
# File lib/honeybadger/notice.rb, line 533 def unwrap_causes(cause) causes, c, i = [], cause, 0 while c && i < MAX_EXCEPTION_CAUSES causes << Cause.new(c) i += 1 c = exception_cause(c) end causes end
Unwrap the exception so that original exception is ignored or reported.
- exception
-
The exception which was rescued.
Returns¶ ↑
Returns the Exception to report.
# File lib/honeybadger/notice.rb, line 507 def unwrap_exception(exception) return exception unless config[:'exceptions.unwrap'] exception_cause(exception) || exception end
Deprecated
↑ topAttributes
Excerpt from source file.