airbrake 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/airbrake.rb +30 -0
- data/lib/airbrake/capistrano.rb +6 -0
- data/lib/airbrake/capistrano/capistrano2.rb +38 -0
- data/lib/airbrake/capistrano/capistrano3.rb +21 -0
- data/lib/airbrake/delayed_job.rb +48 -0
- data/lib/airbrake/logger.rb +101 -0
- data/lib/airbrake/rack.rb +35 -0
- data/lib/airbrake/rack/context_filter.rb +58 -0
- data/lib/airbrake/rack/http_headers_filter.rb +42 -0
- data/lib/airbrake/rack/http_params_filter.rb +25 -0
- data/lib/airbrake/rack/instrumentable.rb +28 -0
- data/lib/airbrake/rack/middleware.rb +100 -0
- data/lib/airbrake/rack/request_body_filter.rb +31 -0
- data/lib/airbrake/rack/request_store.rb +32 -0
- data/lib/airbrake/rack/route_filter.rb +53 -0
- data/lib/airbrake/rack/session_filter.rb +23 -0
- data/lib/airbrake/rack/user.rb +70 -0
- data/lib/airbrake/rack/user_filter.rb +23 -0
- data/lib/airbrake/rails.rb +32 -0
- data/lib/airbrake/rails/action_cable.rb +33 -0
- data/lib/airbrake/rails/action_cable/notify_callback.rb +20 -0
- data/lib/airbrake/rails/action_controller.rb +35 -0
- data/lib/airbrake/rails/action_controller_notify_subscriber.rb +28 -0
- data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +46 -0
- data/lib/airbrake/rails/action_controller_route_subscriber.rb +46 -0
- data/lib/airbrake/rails/active_job.rb +33 -0
- data/lib/airbrake/rails/active_record.rb +34 -0
- data/lib/airbrake/rails/active_record_subscriber.rb +42 -0
- data/lib/airbrake/rails/app.rb +43 -0
- data/lib/airbrake/rails/backtrace_cleaner.rb +10 -0
- data/lib/airbrake/rails/curb.rb +35 -0
- data/lib/airbrake/rails/event.rb +83 -0
- data/lib/airbrake/rails/excon_subscriber.rb +21 -0
- data/lib/airbrake/rails/http.rb +12 -0
- data/lib/airbrake/rails/http_client.rb +10 -0
- data/lib/airbrake/rails/net_http.rb +10 -0
- data/lib/airbrake/rails/railtie.rb +141 -0
- data/lib/airbrake/rails/typhoeus.rb +12 -0
- data/lib/airbrake/rake.rb +63 -0
- data/lib/airbrake/rake/tasks.rb +110 -0
- data/lib/airbrake/resque.rb +29 -0
- data/lib/airbrake/shoryuken.rb +40 -0
- data/lib/airbrake/sidekiq.rb +47 -0
- data/lib/airbrake/sidekiq/retryable_jobs_filter.rb +51 -0
- data/lib/airbrake/sneakers.rb +34 -0
- data/lib/airbrake/version.rb +5 -0
- data/lib/generators/airbrake_generator.rb +23 -0
- data/lib/generators/airbrake_initializer.rb.erb +78 -0
- metadata +416 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
# Monkey-patch to measure request timing.
|
2
|
+
class HTTPClient
|
3
|
+
alias do_get_without_airbrake do_get_block
|
4
|
+
|
5
|
+
def do_get_block(request, proxy, connection, &block)
|
6
|
+
Airbrake::Rack.capture_timing(:http) do
|
7
|
+
do_get_without_airbrake(request, proxy, connection, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Monkey-patch Net::HTTP to benchmark it.
|
2
|
+
Net::HTTP.class_eval do
|
3
|
+
alias_method :request_without_airbrake, :request
|
4
|
+
|
5
|
+
def request(request, *args, &block)
|
6
|
+
Airbrake::Rack.capture_timing(:http) do
|
7
|
+
request_without_airbrake(request, *args, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Rails
|
3
|
+
# This railtie works for any Rails application that supports railties (Rails
|
4
|
+
# 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
|
5
|
+
# occurring in the application automatically.
|
6
|
+
class Railtie < ::Rails::Railtie
|
7
|
+
initializer('airbrake.middleware') do |app|
|
8
|
+
# Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
|
9
|
+
# responsible for logging exceptions and showing a debugging page in
|
10
|
+
# case the request is local. We want to insert our middleware after
|
11
|
+
# DebugExceptions, so we don't notify Airbrake about local requests.
|
12
|
+
|
13
|
+
if ::Rails.version.to_i >= 5
|
14
|
+
# Avoid the warning about deprecated strings.
|
15
|
+
# Insert after DebugExceptions, since ConnectionManagement doesn't
|
16
|
+
# exist in Rails 5 anymore.
|
17
|
+
app.config.middleware.insert_after(
|
18
|
+
ActionDispatch::DebugExceptions,
|
19
|
+
Airbrake::Rack::Middleware
|
20
|
+
)
|
21
|
+
elsif defined?(::ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
22
|
+
# Insert after ConnectionManagement to avoid DB connection leakage:
|
23
|
+
# https://github.com/airbrake/airbrake/pull/568
|
24
|
+
app.config.middleware.insert_after(
|
25
|
+
::ActiveRecord::ConnectionAdapters::ConnectionManagement,
|
26
|
+
'Airbrake::Rack::Middleware'
|
27
|
+
)
|
28
|
+
else
|
29
|
+
# Insert after DebugExceptions for apps without ActiveRecord.
|
30
|
+
app.config.middleware.insert_after(
|
31
|
+
ActionDispatch::DebugExceptions,
|
32
|
+
'Airbrake::Rack::Middleware'
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
rake_tasks do
|
38
|
+
# Report exceptions occurring in Rake tasks.
|
39
|
+
require 'airbrake/rake'
|
40
|
+
|
41
|
+
# Defines tasks such as `airbrake:test` & `airbrake:deploy`.
|
42
|
+
require 'airbrake/rake/tasks'
|
43
|
+
end
|
44
|
+
|
45
|
+
# rubocop:disable Metrics/BlockLength
|
46
|
+
initializer('airbrake.action_controller') do
|
47
|
+
ActiveSupport.on_load(:action_controller, run_once: true) do
|
48
|
+
# Patches ActionController with methods that allow us to retrieve
|
49
|
+
# interesting request data. Appends that information to notices.
|
50
|
+
require 'airbrake/rails/action_controller'
|
51
|
+
include Airbrake::Rails::ActionController
|
52
|
+
|
53
|
+
if Airbrake::Config.instance.performance_stats
|
54
|
+
# Cache route information for the duration of the request.
|
55
|
+
require 'airbrake/rails/action_controller_route_subscriber'
|
56
|
+
ActiveSupport::Notifications.subscribe(
|
57
|
+
'start_processing.action_controller',
|
58
|
+
Airbrake::Rails::ActionControllerRouteSubscriber.new
|
59
|
+
)
|
60
|
+
|
61
|
+
# Send route stats.
|
62
|
+
require 'airbrake/rails/action_controller_notify_subscriber'
|
63
|
+
ActiveSupport::Notifications.subscribe(
|
64
|
+
'process_action.action_controller',
|
65
|
+
Airbrake::Rails::ActionControllerNotifySubscriber.new
|
66
|
+
)
|
67
|
+
|
68
|
+
# Send performance breakdown: where a request spends its time.
|
69
|
+
require 'airbrake/rails/action_controller_performance_breakdown_subscriber'
|
70
|
+
ActiveSupport::Notifications.subscribe(
|
71
|
+
'process_action.action_controller',
|
72
|
+
Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber.new
|
73
|
+
)
|
74
|
+
|
75
|
+
require 'airbrake/rails/net_http' if defined?(Net) && defined?(Net::HTTP)
|
76
|
+
|
77
|
+
if defined?(Curl) && defined?(Curl::CURB_VERSION)
|
78
|
+
require 'airbrake/rails/curb'
|
79
|
+
end
|
80
|
+
|
81
|
+
require 'airbrake/rails/http' if defined?(HTTP) && defined?(HTTP::Client)
|
82
|
+
require 'airbrake/rails/http_client' if defined?(HTTPClient)
|
83
|
+
require 'airbrake/rails/typhoeus' if defined?(Typhoeus)
|
84
|
+
|
85
|
+
if defined?(Excon)
|
86
|
+
require 'airbrake/rails/excon_subscriber'
|
87
|
+
ActiveSupport::Notifications.subscribe(/excon/, Airbrake::Rails::Excon.new)
|
88
|
+
::Excon.defaults[:instrumentor] = ActiveSupport::Notifications
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
# rubocop:enable Metrics/BlockLength
|
94
|
+
|
95
|
+
initializer('airbrake.active_record') do
|
96
|
+
ActiveSupport.on_load(:active_record, run_once: true) do
|
97
|
+
# Reports exceptions occurring in some bugged ActiveRecord callbacks.
|
98
|
+
# Applicable only to the versions of Rails lower than 4.2.
|
99
|
+
require 'airbrake/rails/active_record'
|
100
|
+
include Airbrake::Rails::ActiveRecord
|
101
|
+
|
102
|
+
if defined?(ActiveRecord) && Airbrake::Config.instance.query_stats
|
103
|
+
# Send SQL queries.
|
104
|
+
require 'airbrake/rails/active_record_subscriber'
|
105
|
+
ActiveSupport::Notifications.subscribe(
|
106
|
+
'sql.active_record', Airbrake::Rails::ActiveRecordSubscriber.new
|
107
|
+
)
|
108
|
+
|
109
|
+
# Filter out parameters from SQL body.
|
110
|
+
Airbrake.add_performance_filter(
|
111
|
+
Airbrake::Filters::SqlFilter.new(
|
112
|
+
::ActiveRecord::Base.connection_config[:adapter]
|
113
|
+
)
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
initializer('airbrake.active_job') do
|
120
|
+
ActiveSupport.on_load(:active_job, run_once: true) do
|
121
|
+
# Reports exceptions occurring in ActiveJob jobs.
|
122
|
+
require 'airbrake/rails/active_job'
|
123
|
+
include Airbrake::Rails::ActiveJob
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
initializer('airbrake.action_cable') do
|
128
|
+
ActiveSupport.on_load(:action_cable, run_once: true) do
|
129
|
+
# Reports exceptions occurring in ActionCable connections.
|
130
|
+
require 'airbrake/rails/action_cable'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
runner do
|
135
|
+
at_exit do
|
136
|
+
Airbrake.notify_sync($ERROR_INFO) if $ERROR_INFO
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# This is not bulletproof, but if this file is executed before a task
|
2
|
+
# definition, we can grab tasks descriptions and locations.
|
3
|
+
# See: https://goo.gl/ksn6PE
|
4
|
+
Rake::TaskManager.record_task_metadata = true
|
5
|
+
|
6
|
+
module Rake
|
7
|
+
# Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
|
8
|
+
class Task
|
9
|
+
# Store the original method to use it later.
|
10
|
+
alias execute_without_airbrake execute
|
11
|
+
|
12
|
+
# A wrapper around the original +#execute+, that catches all errors and
|
13
|
+
# notifies Airbrake.
|
14
|
+
#
|
15
|
+
# rubocop:disable Lint/RescueException
|
16
|
+
def execute(args = nil)
|
17
|
+
execute_without_airbrake(args)
|
18
|
+
rescue Exception => ex
|
19
|
+
notify_airbrake(ex, args)
|
20
|
+
raise ex
|
21
|
+
end
|
22
|
+
# rubocop:enable Lint/RescueException
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def notify_airbrake(exception, args)
|
27
|
+
notice = Airbrake.build_notice(exception)
|
28
|
+
notice[:context][:component] = 'rake'
|
29
|
+
notice[:context][:action] = name
|
30
|
+
notice[:params].merge!(
|
31
|
+
rake_task: task_info,
|
32
|
+
execute_args: args,
|
33
|
+
argv: ARGV.join(' ')
|
34
|
+
)
|
35
|
+
|
36
|
+
Airbrake.notify_sync(notice)
|
37
|
+
end
|
38
|
+
|
39
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
40
|
+
def task_info
|
41
|
+
info = {}
|
42
|
+
|
43
|
+
info[:name] = name
|
44
|
+
info[:timestamp] = timestamp.to_s
|
45
|
+
info[:investigation] = investigation
|
46
|
+
|
47
|
+
info[:full_comment] = full_comment if full_comment
|
48
|
+
info[:arg_names] = arg_names if arg_names.any?
|
49
|
+
info[:arg_description] = arg_description if arg_description
|
50
|
+
info[:locations] = locations if locations.any?
|
51
|
+
info[:sources] = sources if sources.any?
|
52
|
+
|
53
|
+
if prerequisite_tasks.any?
|
54
|
+
info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
|
55
|
+
p.__send__(:task_info)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
info
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'airbrake-ruby'
|
2
|
+
|
3
|
+
namespace :airbrake do
|
4
|
+
desc 'Verify your gem installation by sending a test exception'
|
5
|
+
task test: (:environment if defined?(Rails)) do
|
6
|
+
raise Airbrake::Error, 'airbrake-ruby is not configured' unless Airbrake.configured?
|
7
|
+
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
response = Airbrake.notify_sync('Exception from the test Rake task')
|
11
|
+
if response['error']
|
12
|
+
puts "Error: #{response['error']}"
|
13
|
+
elsif response.nil? || response['code']
|
14
|
+
puts <<-ERROR.gsub(/^\s+\|/, '')
|
15
|
+
|#{response['type']}: #{response['message']} (#{response['code']})
|
16
|
+
|
|
17
|
+
|Possible problems:
|
18
|
+
| 1. Project id/key is incorrect
|
19
|
+
| 2. Custom filters ignore the exception we try to send
|
20
|
+
| 3. Environment this task runs in is ignored (see `ignored_environments`)
|
21
|
+
|
|
22
|
+
|If nothing works, please file an issue at: https://github.com/airbrake/airbrake/issues
|
23
|
+
ERROR
|
24
|
+
elsif response['url']
|
25
|
+
puts <<-SUCCESS.gsub(/^\s+\|/, '')
|
26
|
+
|A test exception was sent to Airbrake.
|
27
|
+
|Find it here: #{response['url']}
|
28
|
+
SUCCESS
|
29
|
+
else
|
30
|
+
puts <<-ERROR.gsub(/^\s+\|/, '')
|
31
|
+
|Unexpected error occurred. Response from Airbrake:
|
32
|
+
|#{response}
|
33
|
+
ERROR
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'Notify Airbrake of a new deploy'
|
38
|
+
task :deploy do
|
39
|
+
if defined?(Rails)
|
40
|
+
initializer = Rails.root.join('config', 'initializers', 'airbrake.rb')
|
41
|
+
|
42
|
+
# Avoid loading the environment to speed up the deploy task and try guess
|
43
|
+
# the initializer file location.
|
44
|
+
if initializer.exist? && !Airbrake.configured?
|
45
|
+
load(initializer)
|
46
|
+
else
|
47
|
+
Rake::Task[:environment].invoke
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
raise Airbrake::Error, 'airbrake-ruby is not configured' unless Airbrake.configured?
|
52
|
+
|
53
|
+
deploy_params = {
|
54
|
+
environment: ENV['ENVIRONMENT'],
|
55
|
+
username: ENV['USERNAME'],
|
56
|
+
revision: ENV['REVISION'],
|
57
|
+
repository: ENV['REPOSITORY'],
|
58
|
+
version: ENV['VERSION']
|
59
|
+
}
|
60
|
+
promise = Airbrake.notify_deploy(deploy_params)
|
61
|
+
promise.then do
|
62
|
+
puts "The #{deploy_params[:environment]} environment was deployed."
|
63
|
+
end
|
64
|
+
promise.rescue { |error| abort(error) }
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'Install a Heroku deploy hook to notify Airbrake of deploys'
|
68
|
+
task :install_heroku_deploy_hook do
|
69
|
+
app = ENV['HEROKU_APP']
|
70
|
+
|
71
|
+
config = Bundler.with_clean_env do
|
72
|
+
`heroku config --shell#{ " --app #{app}" if app }`
|
73
|
+
end
|
74
|
+
|
75
|
+
heroku_env = config.each_line.with_object({}) do |line, h|
|
76
|
+
h.merge!(Hash[*line.rstrip.split("\n").flat_map { |v| v.split('=', 2) }])
|
77
|
+
end
|
78
|
+
|
79
|
+
id = heroku_env['AIRBRAKE_PROJECT_ID']
|
80
|
+
key = heroku_env['AIRBRAKE_API_KEY']
|
81
|
+
|
82
|
+
exit!(1) if [id, key].any?(&:nil?)
|
83
|
+
|
84
|
+
unless (env = heroku_env['RAILS_ENV'])
|
85
|
+
env = 'production'
|
86
|
+
puts "Airbrake couldn't identify your app's environment, so the '#{env}'" \
|
87
|
+
" environment will be used."
|
88
|
+
end
|
89
|
+
|
90
|
+
unless (repo = ENV['REPOSITORY_URL'])
|
91
|
+
repo = `git remote get-url origin 2>/dev/null`.chomp
|
92
|
+
if repo.empty?
|
93
|
+
puts "Airbrake couldn't identify your app's repository."
|
94
|
+
else
|
95
|
+
puts "Airbrake couldn't identify your app's repository, so the " \
|
96
|
+
"'origin' remote url '#{repo}' will be used."
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
url = "https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"
|
101
|
+
url << "&environment=#{env}"
|
102
|
+
url << "&repository=#{repo}" unless repo.empty?
|
103
|
+
|
104
|
+
command = %(heroku addons:create deployhooks:http --url="#{url}")
|
105
|
+
command << " --app #{app}" if app
|
106
|
+
|
107
|
+
puts "$ #{command}"
|
108
|
+
Bundler.with_clean_env { puts `#{command}` }
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Resque
|
2
|
+
module Failure
|
3
|
+
# Provides Resque integration with Airbrake.
|
4
|
+
#
|
5
|
+
# @since v5.0.0
|
6
|
+
# @see https://github.com/resque/resque/wiki/Failure-Backends
|
7
|
+
class Airbrake < Base
|
8
|
+
def save
|
9
|
+
::Airbrake.notify_sync(exception, payload) do |notice|
|
10
|
+
notice[:context][:component] = 'resque'
|
11
|
+
notice[:context][:action] = action(payload)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# @return [String] job's name. When ActiveJob is present, retrieve
|
18
|
+
# job_class. When used directly, use worker's name
|
19
|
+
def action(payload)
|
20
|
+
active_job_args = payload['args'].first if payload['args']
|
21
|
+
if active_job_args.is_a?(Hash) && active_job_args['job_class']
|
22
|
+
active_job_args['job_class']
|
23
|
+
else
|
24
|
+
payload['class'].to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Shoryuken
|
3
|
+
# Provides integration with Shoryuken.
|
4
|
+
class ErrorHandler
|
5
|
+
# rubocop:disable Lint/RescueException
|
6
|
+
def call(worker, queue, _sqs_msg, body)
|
7
|
+
yield
|
8
|
+
rescue Exception => exception
|
9
|
+
notify_airbrake(exception, worker, queue, body)
|
10
|
+
|
11
|
+
raise exception
|
12
|
+
end
|
13
|
+
# rubocop:enable Lint/RescueException
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def notify_airbrake(exception, worker, queue, body)
|
18
|
+
Airbrake.notify(exception, notice_context(queue, body)) do |notice|
|
19
|
+
notice[:context][:component] = 'shoryuken'
|
20
|
+
notice[:context][:action] = worker.class.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def notice_context(queue, body)
|
25
|
+
{
|
26
|
+
queue: queue,
|
27
|
+
body: body.is_a?(Array) ? { batch: body } : { body: body }
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if defined?(::Shoryuken)
|
35
|
+
Shoryuken.configure_server do |config|
|
36
|
+
config.server_middleware do |chain|
|
37
|
+
chain.add Airbrake::Shoryuken::ErrorHandler
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'airbrake/sidekiq/retryable_jobs_filter'
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Sidekiq
|
5
|
+
# Provides integration with Sidekiq v2+.
|
6
|
+
class ErrorHandler
|
7
|
+
# rubocop:disable Lint/RescueException
|
8
|
+
def call(_worker, context, _queue)
|
9
|
+
yield
|
10
|
+
rescue Exception => exception
|
11
|
+
notify_airbrake(exception, context)
|
12
|
+
raise exception
|
13
|
+
end
|
14
|
+
# rubocop:enable Lint/RescueException
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def notify_airbrake(exception, context)
|
19
|
+
Airbrake.notify(exception, context) do |notice|
|
20
|
+
notice[:context][:component] = 'sidekiq'
|
21
|
+
notice[:context][:action] = action(context)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] job's name. When ActiveJob is present, retrieve
|
26
|
+
# job_class. When used directly, use worker's name
|
27
|
+
def action(context)
|
28
|
+
klass = context['class'] || context[:job] && context[:job]['class']
|
29
|
+
return klass unless context[:job] && context[:job]['args'].first.is_a?(Hash)
|
30
|
+
return klass unless (job_class = context[:job]['args'].first['job_class'])
|
31
|
+
job_class
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if Sidekiq::VERSION < '3'
|
38
|
+
Sidekiq.configure_server do |config|
|
39
|
+
config.server_middleware do |chain|
|
40
|
+
chain.add(Airbrake::Sidekiq::ErrorHandler)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
Sidekiq.configure_server do |config|
|
45
|
+
config.error_handlers << Airbrake::Sidekiq::ErrorHandler.new.method(:notify_airbrake)
|
46
|
+
end
|
47
|
+
end
|