Module: Bugsnag

Defined in:
lib/bugsnag.rb,
lib/bugsnag/report.rb,
lib/bugsnag/cleaner.rb,
lib/bugsnag/helpers.rb,
lib/bugsnag/version.rb,
lib/bugsnag/delivery.rb,
lib/bugsnag/meta_data.rb,
lib/bugsnag/stacktrace.rb,
lib/bugsnag/configuration.rb,
lib/bugsnag/session_tracker.rb,
lib/bugsnag/middleware_stack.rb,
lib/bugsnag/integrations/rack.rb,
lib/bugsnag/integrations/rake.rb,
lib/bugsnag/integrations/mongo.rb,
lib/bugsnag/integrations/resque.rb,
lib/bugsnag/delivery/synchronous.rb,
lib/bugsnag/integrations/mailman.rb,
lib/bugsnag/integrations/railtie.rb,
lib/bugsnag/integrations/sidekiq.rb,
lib/bugsnag/delivery/thread_queue.rb,
lib/bugsnag/integrations/shoryuken.rb

Defined Under Namespace

Modules: Breadcrumbs, Delivery, Helpers, MetaData, Middleware, Rails, RakeTask, Utility Classes: Cleaner, Configuration, Mailman, MiddlewareStack, MongoBreadcrumbSubscriber, Rack, Railtie, Report, Resque, SessionTracker, Shoryuken, Sidekiq, Stacktrace

Constant Summary collapse

LOCK =
Mutex.new
INTEGRATIONS =
[:resque, :sidekiq, :mailman, :delayed_job, :shoryuken, :que, :mongo]
NIL_EXCEPTION_DESCRIPTION =
"'nil' was notified as an exception"
VERSION =
File.read(File.join(File.dirname(__FILE__), "../../VERSION")).strip

Class Method Summary collapse

Class Method Details

.at_exit_handler_installed?Boolean

Checks if an at_exit handler has been added

Returns:

  • (Boolean)


143
144
145
# File 'lib/bugsnag.rb', line 143

def at_exit_handler_installed?
  @exit_handler_added ||= false
end

.before_notify_callbacksObject

Allow access to “before notify” callbacks as an array.

These callbacks will be called whenever an error notification is being made.



174
175
176
# File 'lib/bugsnag.rb', line 174

def before_notify_callbacks
  Bugsnag.configuration.request_data[:before_callbacks] ||= []
end

.configurationObject

Configuration getters

Returns the client’s Configuration object, or creates one if not yet created.



150
151
152
153
# File 'lib/bugsnag.rb', line 150

def configuration
  @configuration = nil unless defined?(@configuration)
  @configuration || LOCK.synchronize { @configuration ||= Bugsnag::Configuration.new }
end

.configure(validate_api_key = true) {|configuration| ... } ⇒ Object

Configure the Bugsnag notifier application-wide settings.

Yields a configuration object to use to set application settings.

Yields:



47
48
49
50
51
52
53
54
# File 'lib/bugsnag.rb', line 47

def configure(validate_api_key=true)
  yield(configuration) if block_given?

  check_key_valid if validate_api_key
  check_endpoint_setup

  register_at_exit
end

.leave_breadcrumb(name, meta_data = {}, type = Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE, auto = :manual) ⇒ Object

Leave a breadcrumb to be attached to subsequent reports

Parameters:

  • name (String)

    the main breadcrumb name/message

  • meta_data (Hash) (defaults to: {})

    String, Numeric, or Boolean meta data to attach

  • type (String) (defaults to: Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE)

    the breadcrumb type, from Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES

  • auto (Symbol) (defaults to: :manual)

    set to :auto if the breadcrumb is automatically created



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/bugsnag.rb', line 206

def leave_breadcrumb(name, ={}, type=Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE, auto=:manual)
  breadcrumb = Bugsnag::Breadcrumbs::Breadcrumb.new(name, type, , auto)
  validator = Bugsnag::Breadcrumbs::Validator.new(configuration)

  # Initial validation
  validator.validate(breadcrumb)

  # Skip if it's already invalid
  unless breadcrumb.ignore?
    # Run callbacks
    configuration.before_breadcrumb_callbacks.each do |c|
      c.arity > 0 ? c.call(breadcrumb) : c.call
      break if breadcrumb.ignore?
    end

    # Return early if ignored
    return if breadcrumb.ignore?

    # Validate again in case of callback alteration
    validator.validate(breadcrumb)

    # Add to breadcrumbs buffer if still valid
    configuration.breadcrumbs << breadcrumb unless breadcrumb.ignore?
  end
end

.load_integration(integration) ⇒ Object

Load a specific integration



190
191
192
193
194
195
196
197
# File 'lib/bugsnag.rb', line 190

def load_integration(integration)
  integration = :railtie if integration == :rails
  if INTEGRATIONS.include?(integration) || integration == :railtie
    require "bugsnag/integrations/#{integration}"
  else
    configuration.debug("Integration #{integration} is not currently supported")
  end
end

.load_integrationsObject

Attempts to load all integrations through auto-discovery



179
180
181
182
183
184
185
186
187
# File 'lib/bugsnag.rb', line 179

def load_integrations
  require "bugsnag/integrations/railtie" if defined?(Rails::Railtie)
  INTEGRATIONS.each do |integration|
    begin
      require "bugsnag/integrations/#{integration}"
    rescue LoadError
    end
  end
end

.notify(exception, auto_notify = false) {|report| ... } ⇒ Object

Explicitly notify of an exception.

Optionally accepts a block to append metadata to the yielded report.

Yields:

  • (report)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/bugsnag.rb', line 60

def notify(exception, auto_notify=false, &block)
  unless auto_notify.is_a? TrueClass or auto_notify.is_a? FalseClass
    configuration.warn("Adding metadata/severity using a hash is no longer supported, please use block syntax instead")
    auto_notify = false
  end

  return unless deliver_notification?(exception, auto_notify)

  exception = NIL_EXCEPTION_DESCRIPTION if exception.nil?

  report = Report.new(exception, configuration, auto_notify)

  # If this is an auto_notify we yield the block before the any middleware is run
  yield(report) if block_given? && auto_notify
  if report.ignore?
    configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in auto_notify block")
    return
  end

  # Run internal middleware
  configuration.internal_middleware.run(report)
  if report.ignore?
    configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in internal middlewares")
    return
  end

  # Store before_middleware severity reason for future reference
  initial_severity = report.severity
  initial_reason = report.severity_reason

  # Run users middleware
  configuration.middleware.run(report) do
    if report.ignore?
      configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in user provided middleware")
      return
    end

    # If this is not an auto_notify then the block was provided by the user. This should be the last
    # block that is run as it is the users "most specific" block.
    yield(report) if block_given? && !auto_notify
    if report.ignore?
      configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in user provided block")
      return
    end

    # Test whether severity has been changed and ensure severity_reason is consistant in auto_notify case
    if report.severity != initial_severity
      report.severity_reason = {
        :type => Report::USER_CALLBACK_SET_SEVERITY
      }
    else
      report.severity_reason = initial_reason
    end

    # Deliver
    configuration.info("Notifying #{configuration.notify_endpoint} of #{report.exceptions.last[:errorClass]}")
    options = {:headers => report.headers}
    payload = ::JSON.dump(Bugsnag::Helpers.trim_if_needed(report.as_json))
    Bugsnag::Delivery[configuration.delivery_method].deliver(configuration.notify_endpoint, payload, configuration, options)
    report_summary = report.summary
    leave_breadcrumb(report_summary[:error_class], report_summary, Bugsnag::Breadcrumbs::ERROR_BREADCRUMB_TYPE, :auto)
  end
end

.register_at_exitObject

Registers an at_exit function to automatically catch errors on exit



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/bugsnag.rb', line 126

def register_at_exit
  return if at_exit_handler_installed?
  @exit_handler_added = true
  at_exit do
    if $!
      Bugsnag.notify($!, true) do |report|
        report.severity = 'error'
        report.severity_reason = {
          :type => Bugsnag::Report::UNHANDLED_EXCEPTION
        }
      end
    end
  end
end

.session_trackerObject

Returns the client’s SessionTracker object, or creates one if not yet created.



157
158
159
160
# File 'lib/bugsnag.rb', line 157

def session_tracker
  @session_tracker = nil unless defined?(@session_tracker)
  @session_tracker || LOCK.synchronize { @session_tracker ||= Bugsnag::SessionTracker.new}
end

.start_sessionObject

Starts a session.

Allows Bugsnag to track error rates across releases.



166
167
168
# File 'lib/bugsnag.rb', line 166

def start_session
  session_tracker.start_session
end