class Honeybadger::Agent
The Honeybadger
agent contains all the methods for interacting with the Honeybadger
service. It can be used to send notifications to multiple projects in large apps. The global agent instance ({Agent.instance}) should always be accessed through the {Honeybadger} singleton.
=== Context
Context is global by default, meaning agents created via Honeybadger::Agent.new
will share context (added via Honeybadger.context
or {Honeybadger::Agent#context}) with other agents. This also includes the Rack
environment when using the {Honeybadger::Rack::ErrorNotifier} middleware. To localize context for a custom agent, use the +local_context: true+ option when initializing.
@example
# Standard usage: OtherBadger = Honeybadger::Agent.new # With local context: OtherBadger = Honeybadger::Agent.new(local_context: true) OtherBadger.configure do |config| config.api_key = 'project api key' end begin # Risky operation rescue => e OtherBadger.notify(e) end
Attributes
@api private
@api private
Public Class Methods
@api private
# File lib/honeybadger/agent.rb, line 50 def self.instance @instance end
@api private
# File lib/honeybadger/agent.rb, line 55 def self.instance=(instance) @instance = instance end
# File lib/honeybadger/agent.rb, line 59 def initialize(opts = {}) if opts.kind_of?(Config) @config = opts opts = {} end @context = opts.delete(:context) local_context = opts.delete(:local_context) @config ||= Config.new(opts) if local_context @context ||= ContextManager.new @breadcrumbs = Breadcrumbs::Collector.new(config) else @breadcrumbs = nil end init_worker end
Public Instance Methods
Perform a synchronous check_in.
@example Honeybadger.check_in('1MqIo1')
@param [String] id The unique check in id (e.g. '1MqIo1') or the check in url.
@return [Boolean] true if the check in was successful and false otherwise.
# File lib/honeybadger/agent.rb, line 186 def check_in(id) # this is to allow check ins even if a url is passed check_in_id = id.to_s.strip.gsub(/\/$/, '').split('/').last response = backend.check_in(check_in_id) response.success? end
Clear all transaction scoped data.
# File lib/honeybadger/agent.rb, line 259 def clear! context_manager.clear! breadcrumbs.clear! end
Save global context for the current request.
@example Honeybadger.context({my_data: 'my value'})
# Inside a Rails controller: before_action do Honeybadger.context({user_id: current_user.id}) end # Explicit conversion class User < ActiveRecord::Base def to_honeybadger_context { user_id: id, user_email: email } end end user = User.first Honeybadger.context(user) # Clearing global context: Honeybadger.context.clear!
@param [Hash] context A Hash of data which will be sent to Honeybadger
when an error occurs. If the object responds to #to_honeybadger_context
, the return value of that method will be used (explicit conversion). Can include any key/value, but a few keys have a special meaning in Honeybadger
.
@option context [String] :user_id The user ID used by Honeybadger
to aggregate user data across occurrences on the error page (optional). @option context [String] :user_email The user email address (optional). @option context [String] :tags The comma-separated list of tags. When present, tags will be applied to errors with this context (optional).
@return [self] so that method calls can be chained.
# File lib/honeybadger/agent.rb, line 253 def context(context = nil) context_manager.set_context(context) unless context.nil? self end
Flushes all data from workers before returning. This is most useful in tests when using the test backend, where normally the asynchronous nature of this library could create race conditions.
@example # Without a block: it “sends a notification to Honeybadger” do expect { Honeybadger.notify
(StandardError.new('test backend')) Honeybadger.flush }.to change(Honeybadger::Backend::Test.notifications, :size).by(0) end
# With a block: it "sends a notification to Honeybadger" do expect { Honeybadger.flush do 49.times do Honeybadger.notify(StandardError.new('test backend')) end end }.to change(Honeybadger::Backend::Test.notifications[:notices], :size).by(49) end
@yield An optional block to execute (exceptions will propagate after data is flushed).
@return [Object, Boolean] value of block if block is given, otherwise true on success or false if Honeybadger
isn't running.
# File lib/honeybadger/agent.rb, line 344 def flush return true unless block_given? yield ensure worker.flush end
Get global context for the current request.
@example Honeybadger.context({my_data: 'my value'}) Honeybadger.get_context # => {my_data: 'my value'}
@return [Hash, nil]
# File lib/honeybadger/agent.rb, line 271 def get_context context_manager.get_context end
Sends an exception to Honeybadger
. Does not report ignored exceptions by default.
@example # With an exception: begin fail 'oops' rescue => exception Honeybadger.notify
(exception, context: { my_data: 'value' }) # => '-1dfb92ae-9b01-42e9-9c13-31205b70744a' end
# Custom notification: Honeybadger.notify('Something went wrong.', { error_class: 'MyClass', context: {my_data: 'value'} }) # => '06220c5a-b471-41e5-baeb-de247da45a56'
@param [Exception, Hash, Object] exception_or_opts An Exception object, or a Hash of options which is used to build the notice. All other types of objects will be converted to a String and used as the :error_message. @param [Hash] opts The options Hash when the first argument is an Exception.
@option opts [String] :error_message The error message. @option opts [String] :error_class ('Notice') The class name of the error. @option opts [Array] :backtrace The backtrace of the error (optional). @option opts [String] :fingerprint The grouping fingerprint of the exception (optional). @option opts [Boolean] :force (false) Always report the exception when true, even when ignored (optional). @option opts [Boolean] :sync (false) Send data synchronously (skips the worker) (optional). @option opts [String] :tags The comma-separated list of tags (optional). @option opts [Hash] :context The context to associate with the exception (optional). @option opts [String] :controller The controller name (such as a Rails controller) (optional). @option opts [String] :action The action name (such as a Rails controller action) (optional). @option opts [Hash] :parameters The HTTP request paramaters (optional). @option opts [Hash] :session The HTTP request session (optional). @option opts [String] :url The HTTP request URL (optional). @option opts [Exception] :cause The cause for this error (optional).
@return [String] UUID reference to the notice within Honeybadger
. @return [false] when ignored.
# File lib/honeybadger/agent.rb, line 121 def notify(exception_or_opts, opts = {}) opts = opts.dup if exception_or_opts.is_a?(Exception) opts[:exception] = exception_or_opts elsif exception_or_opts.respond_to?(:to_hash) opts.merge!(exception_or_opts.to_hash) else opts[:error_message] = exception_or_opts.to_s end validate_notify_opts!(opts) add_breadcrumb( "Honeybadger Notice", metadata: opts, category: "notice" ) if config[:'breadcrumbs.enabled'] opts[:rack_env] ||= context_manager.get_rack_env opts[:global_context] ||= context_manager.get_context opts[:breadcrumbs] ||= breadcrumbs.dup notice = Notice.new(config, opts) config.before_notify_hooks.each do |hook| break if notice.halted? with_error_handling { hook.call(notice) } end unless notice.api_key =~ NOT_BLANK error { sprintf('Unable to send error report: API key is missing. id=%s', notice.id) } return false end if !opts[:force] && notice.ignore? debug { sprintf('ignore notice feature=notices id=%s', notice.id) } return false end if notice.halted? debug { 'halted notice feature=notices' } return false end info { sprintf('Reporting error id=%s', notice.id) } if opts[:sync] || config[:sync] send_now(notice) else push(notice) end notice.id end
Stops the Honeybadger
service.
@example Honeybadger.stop # => nil
# File lib/honeybadger/agent.rb, line 355 def stop(force = false) worker.shutdown(force) true end
Track a new deployment
@example Honeybadger.track_deployment(revision: 'be2ceb6')
@param [String] :environment The environment name. Defaults to the current configured environment. @param [String] :revision The VCS revision being deployed. Defaults to the currently configured revision. @param [String] :local_username The name of the user who performed the deploy. @param [String] :repository The base URL of the VCS repository. It should be HTTPS-style.
@return [Boolean] true if the deployment was successfully tracked and false otherwise.
# File lib/honeybadger/agent.rb, line 205 def track_deployment(environment: nil, revision: nil, local_username: nil, repository: nil) opts = { environment: environment || config[:env], revision: revision || config[:revision], local_username: local_username, repository: repository } response = backend.track_deployment(opts) response.success? end
@api private
# File lib/honeybadger/agent.rb, line 424 def with_rack_env(rack_env, &block) context_manager.set_rack_env(rack_env) yield ensure context_manager.set_rack_env(nil) end
Private Instance Methods
# File lib/honeybadger/agent.rb, line 454 def context_manager return @context if @context ContextManager.current end
# File lib/honeybadger/agent.rb, line 469 def init_worker @worker = Worker.new(config) end
# File lib/honeybadger/agent.rb, line 459 def push(object) worker.push(object) true end
# File lib/honeybadger/agent.rb, line 464 def send_now(object) worker.send_now(object) true end
# File lib/honeybadger/agent.rb, line 446 def validate_notify_opts!(opts) return if opts.has_key?(:exception) return if opts.has_key?(:error_message) msg = sprintf('`Honeybadger.notify` was called with invalid arguments. You must pass either an Exception or options Hash containing the `:error_message` key. location=%s', caller[caller.size-1]) raise ArgumentError.new(msg) if config.dev? warn(msg) end
# File lib/honeybadger/agent.rb, line 473 def with_error_handling yield rescue => ex error { "Rescued an error in a before notify hook: #{ex.message}" } end